home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / AppsToGo / DTS.Lib / Window2.c < prev   
Encoding:
C/C++ Source or Header  |  1994-03-24  |  96.1 KB  |  3,828 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     DTS.Lib
  5. ** File:        window2.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1993 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12. /* You may incorporate this sample code into your applications without
  13. ** restriction, though the sample code has been provided "AS IS" and the
  14. ** responsibility for its operation is 100% yours.  However, what you are
  15. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  16. ** after having made changes. If you're going to re-distribute the source,
  17. ** we require that you make it clear in the source that the code was
  18. ** descended from Apple Sample Code, but that you've made changes. */
  19.  
  20.  
  21.  
  22. /*****************************************************************************/
  23.  
  24.  
  25.  
  26. #include "DTS.Lib2.h"
  27. #include "DTS.Lib.protos.h"
  28.  
  29. #ifndef __BALLOONS__
  30. #include <Balloons.h>
  31. #endif
  32.  
  33. #ifndef __DESK__
  34. #include <Desk.h>
  35. #endif
  36.  
  37. #ifndef __ERRORS__
  38. #include <Errors.h>
  39. #endif
  40.  
  41. #ifndef __FONTS__
  42. #include <Fonts.h>
  43. #endif
  44.  
  45. #ifndef __CLPROCS__
  46. #include "ListControlProcs.h"
  47. #endif
  48.  
  49. #ifndef __LOWMEM__
  50. #include <LowMem.h>
  51. #endif
  52.  
  53. #ifndef __MOVIES__
  54. #include <Movies.h>
  55. #endif
  56.  
  57. #ifndef __RESOURCES__
  58. #include <Resources.h>
  59. #endif
  60.  
  61. #ifndef __SCRIPT__
  62. #include <Script.h>
  63. #endif
  64.  
  65. #ifndef __TOOLUTILS__
  66. #include <ToolUtils.h>
  67. #endif
  68.  
  69. #ifndef __UTILITIES__
  70. #include "Utilities.h"
  71. #endif
  72.  
  73.  
  74.  
  75. /*****************************************************************************/
  76.  
  77.  
  78. #if defined(powerc) || defined (__powerc)
  79. #pragma options align=mac68k
  80. #endif
  81. typedef struct {
  82.     Rect            contrlRect;
  83.     short            contrlValue;
  84.     unsigned char    contrlVis;
  85.     short            contrlMax;
  86.     short            contrlMin;
  87.     short            procID;
  88.     long            contrlRfCon;
  89.     Str255            contrlTitle;
  90. } CtlTemplate;
  91. #if defined(powerc) || defined(__powerc)
  92. #pragma options align=reset
  93. #endif
  94.  
  95. extern short    gTECtl;
  96. extern short    gListCtl;
  97. extern short    gCIconCtl;
  98. extern short    gPICTCtl;
  99. extern short    gDataCtl;
  100.  
  101. extern Handle    gPopupProc;
  102.  
  103. extern short            gPrintPage;                    /* Non-zero means we are printing. */
  104. extern short            gMinVersion, gMaxVersion;
  105. extern Boolean            gInBackground;
  106. extern WindowTemplate    gWindowTemplate, gOpenedWindowTemplate;
  107.  
  108. extern short            gTypeListLen;
  109. extern SFTypeList        gTypeList;
  110. extern long                gAppWindowAttr;
  111. extern OSType            gAppWindowType;
  112. extern Boolean            gNoDefaultDocument;
  113. extern OSErr            gGetWindowErr;
  114.  
  115. OSType                *gTypeListPtr = gTypeList;
  116. short                gBeginUpdateNested;
  117. TreeObjHndl            gWindowFormats;
  118. OSErr                gDialogErr;
  119. HideWindowProcPtr    gHideWindowProc;
  120.  
  121. static RgnHandle    gKeepUpdateRgn;
  122. static WindowPtr    gOldPort;
  123.  
  124. RgnHandle    gCursorRgn;
  125.     /* The current cursor region.  The initial cursor region is an empty
  126.     ** region, which will cause WaitNextEvent to generate a mouse-moved
  127.     ** event, which will cause us to set the cursor for the first time. */
  128.  
  129. static Cursor    gCursor;
  130. CursPtr            gCursorPtr;
  131.     /* The current cursor that applies to gCursorRgn.  These values
  132.     ** are here to shorten the re-processing time for determining the
  133.     ** correct cursor after an event.  This is specifically so that characters
  134.     ** can be typed into the TextEdit control faster.  If we spend a great
  135.     ** deal of time per-event recalculating the cursor region, text entry for
  136.     ** the TextEdit control slows down considerably.  If you want to override
  137.     ** the time savings because you are changing the cursor directly, either
  138.     ** set gCursorPtr to nil, or call DoSetCursor to set the cursor.
  139.     ** DoSetCursor simply sets gCursorPtr to nil, as well as setting
  140.     ** the cursor. */
  141.  
  142. static Rect                    OldLocWindow(WindowPtr window, WindowPtr relatedWindow, Rect sizeInfo);
  143. static PositionWndProcPtr    gOldLocProc;
  144.  
  145. static pascal void    DefaultScrollAction(ControlHandle scrollCtl, short part);
  146. static Boolean        DefaultScroll(ControlHandle ctl, short part, EventRecord *event);
  147.  
  148.  
  149.  
  150. /*****************************************************************************/
  151. /*****************************************************************************/
  152.  
  153.  
  154.  
  155. /* This function creates a new application window.  An application window
  156. ** contains a document which is referenced by a handle in the refCon field. */
  157.  
  158. #pragma segment Window
  159. OSErr    DoNewWindow(FileRecHndl frHndl, WindowPtr *retWindow, WindowPtr relatedWindow, WindowPtr behind)
  160. {
  161.     WindowPtr            oldPort, window;
  162.     FileRecHndl            ffrHndl;
  163.     ControlHandle        ctl;
  164.     Rect                ctlRect, contRect, userState, sizeInfo, rct, rct2, msrct, oldPlaceRct;
  165.     short                h, v, hDocSize, vDocSize;
  166.     long                wkind, wwkind, attributes;
  167.     OSErr                err;
  168.     PositionWndProcPtr    proc;
  169.     GDHandle            device;
  170.     PixMapHandle        pmap;
  171.  
  172.     gCursorPtr = nil;        /* Force recalc of cursor. */
  173.  
  174.     if (!frHndl) return(noErr);
  175.     attributes = (*frHndl)->fileState.attributes;
  176.  
  177.     err = noErr;
  178.     GetPort(&oldPort);
  179.  
  180.     proc = (*frHndl)->fileState.getDocWindow;
  181.  
  182.     if (attributes & kwStaggerWindow) proc = StaggerWindow;
  183.     if (attributes & kwCenterWindow)  proc = CenterWindow;
  184.  
  185.     gOldLocProc = proc;
  186.     if (attributes & kwOpenAtOldLoc)  proc = OldLocWindow;            /* Try to open window at old location. */
  187.  
  188.     SetRect(&sizeInfo, 0, 0, 0, 0);
  189.     if ((proc == StaggerWindow) || (proc == OldLocWindow)) {
  190.         hDocSize = (*frHndl)->d.doc.fhInfo.hDocSize;
  191.         vDocSize = (*frHndl)->d.doc.fhInfo.vDocSize;
  192.         if (hDocSize) {
  193.             hDocSize += (*frHndl)->fileState.leftSidebar;
  194.             if (attributes & kwHScroll)
  195.                 if (vDocSize)
  196.                     vDocSize += 15;
  197.         }
  198.         if (vDocSize) {
  199.             vDocSize += (*frHndl)->fileState.topSidebar;
  200.             if (attributes & kwVScroll)
  201.                 if (hDocSize)
  202.                     hDocSize += 15;
  203.         }
  204.         SetRect(&sizeInfo, hDocSize, vDocSize, hDocSize, vDocSize);
  205.     }
  206.  
  207.     wkind = (attributes & (kwIsPalette | kwIsModalDialog));
  208.     if (behind) {
  209.         for (;;) {
  210.             if (!(behind = GetNextWindow(behind, 0))) break;
  211.                 /* break if behind all windows.  behind is nil, so that's what we have. */
  212.             if (!((WindowPeek)behind)->visible) continue;
  213.  
  214.             wwkind = kwIsDocument;
  215.             if (IsAppWindow(behind)) {
  216.                 ffrHndl = (FileRecHndl)GetWRefCon(behind);
  217.                 if (ffrHndl)
  218.                     wwkind  = ((*ffrHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog));
  219.             }
  220.  
  221.             if (wkind >= wwkind) {
  222.                 for (;;) {
  223.                     behind = GetPreviousWindow(behind);
  224.                     if (behind == (WindowPtr)-1)       break;
  225.                     if (((WindowPeek)behind)->visible) break;
  226.                 }
  227.                 break;
  228.             }
  229.         }
  230.     }
  231.  
  232.     oldPlaceRct = SetWindowPlacementRect(nil);
  233.     if (EmptyRect(&oldPlaceRct)) {
  234.  
  235.         if (attributes & kwSameMonitor) {
  236.             relatedWindow = nil;
  237.             for (; (relatedWindow = GetNextWindow(relatedWindow, (*frHndl)->fileState.sfType)) != nil;)
  238.                 if (((WindowPeek)relatedWindow)->visible) break;
  239.             if (!relatedWindow) {
  240.                 for (; (relatedWindow = GetNextWindow(relatedWindow, 0)) != nil;) {
  241.                     if (!((WindowPeek)relatedWindow)->visible) continue;
  242.                     if (((WindowPeek)relatedWindow)->windowKind >= 1000) {
  243.                         ffrHndl = (FileRecHndl)GetWRefCon(relatedWindow);
  244.                         if (ffrHndl) {
  245.                             wwkind = (*ffrHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  246.                             if (wkind == wwkind) break;
  247.                         }
  248.                     }
  249.                 }
  250.             }
  251.         }
  252.  
  253.         if ((!(attributes & kwSameMonitor)) || (!relatedWindow)) {
  254.             if (attributes & (kwColorMonitor | kwSecondaryMonitor)) {
  255.     
  256.                 if (gQDVersion > kQDOriginal) {
  257.                     rct = msrct = GetMainScreenRect();
  258.                     for (device = GetDeviceList(); device; device = GetNextDevice(device)) {
  259.                         rct2 = (*device)->gdRect;
  260.                         if (TestDeviceAttribute(device, screenDevice) &&
  261.                             TestDeviceAttribute(device, screenActive)
  262.                         ) {
  263.                             pmap = (*device)->gdPMap;
  264.                             if (attributes & kwColorMonitor) {
  265.                                 if ((*pmap)->pixelSize > 1) {
  266.                                     rct = rct2;
  267.                                     if (!(rct.top | rct.left)) break;
  268.                                 }
  269.                             }
  270.                             else {
  271.                                 if (!EqualRect(&rct2, &msrct)) {
  272.                                     rct = rct2;
  273.                                     break;
  274.                                 }
  275.                             }
  276.                         }
  277.                     }
  278.                     if (EqualRect(&rct, &msrct))
  279.                         rct.top += GetMBarHeight();
  280.                     SetWindowPlacementRect(&rct);
  281.                 }
  282.             }
  283.         }
  284.     }
  285.  
  286.     window = GetSomeKindOfWindow(proc, (*frHndl)->fileState.windowID, nil, false, relatedWindow,
  287.                                  behind, true, sizeInfo, (long)frHndl);
  288.  
  289.     SetWindowPlacementRect(&oldPlaceRct);
  290.  
  291.     if (window) {
  292.         ((WindowPeek)window)->windowKind = 1000;        /* ID it as an AppsToGo window. */
  293.  
  294.         SetPort(window);
  295.         NewWindowTitle(window, nil);
  296.  
  297.         (*frHndl)->fileState.window = window;
  298.  
  299.         (*frHndl)->fileState.hArrowVal = 16;    /* Default arrow value is 16. */
  300.         (*frHndl)->fileState.vArrowVal = 16;
  301.  
  302.         if (!(*frHndl)->d.doc.fhInfo.hDocSize) {
  303.             h  = gOpenedWindowTemplate.boundsRect.right - gOpenedWindowTemplate.boundsRect.left;
  304.             h -= (*frHndl)->fileState.leftSidebar;    /* Default document size is */
  305.             if (attributes & kwVScroll)                /* content less leftSidebar */
  306.                 h -= 15;                            /* value less scrollbars.   */
  307.             (*frHndl)->d.doc.fhInfo.hDocSize = h;
  308.         }
  309.         if (!(*frHndl)->d.doc.fhInfo.vDocSize) {
  310.             v  = gOpenedWindowTemplate.boundsRect.bottom - gOpenedWindowTemplate.boundsRect.top;
  311.             v -= (*frHndl)->fileState.topSidebar;    /* We don't have to initialize the page */
  312.             if (attributes & kwHScroll)                /* values since the scrollbars won't be */
  313.                 v -= 15;                            /* active until the window is resized   */
  314.             (*frHndl)->d.doc.fhInfo.vDocSize = v;    /* or these values are set elsewhere.   */
  315.         }
  316.  
  317.         if (attributes & kwHScroll) {        /* Caller wants a horizontal scrollbar... */
  318.             ctlRect = window->portRect;
  319.             ctlRect.left += (*frHndl)->fileState.leftSidebar;
  320.             ctlRect.left += (*frHndl)->fileState.hScrollIndent;
  321.             --ctlRect.left;
  322.             ++ctlRect.right;
  323.             ctlRect.top = ++ctlRect.bottom - 16;
  324.             if (attributes & (kwHScrollLessGrow - kwHScroll +  kwGrowIcon))
  325.                 ctlRect.right -= 15;
  326.             OffsetRect(&ctlRect, 0, -16384);
  327.             ctl = NewControl(window, &ctlRect, "\p", true, 0, 0, 0, scrollBarProc, 0L);
  328.             if (ctl)
  329.                 (*frHndl)->fileState.hScroll = ctl;
  330.             else
  331.                 err = memFullErr;
  332.         }
  333.  
  334.         if (!err) {
  335.             if (attributes & kwVScroll) {        /* Caller wants a vertical scrollbar... */
  336.                 ctlRect = window->portRect;
  337.                 ctlRect.top += (*frHndl)->fileState.topSidebar;
  338.                 ctlRect.top += (*frHndl)->fileState.vScrollIndent;
  339.                 --ctlRect.top;
  340.                 ++ctlRect.bottom;
  341.                 ctlRect.left = ++ctlRect.right - 16;
  342.                 if (attributes & (kwVScrollLessGrow - kwVScroll +  kwGrowIcon))
  343.                     ctlRect.bottom -= 15;
  344.                 OffsetRect(&ctlRect, 0, -16384);
  345.                 ctl = NewControl(window, &ctlRect, "\p", true, 0, 0, 0, scrollBarProc, 0L);
  346.                 if (ctl)
  347.                     (*frHndl)->fileState.vScroll = ctl;
  348.                 else
  349.                     err = memFullErr;
  350.             }
  351.         }
  352.  
  353.         if (!err) {
  354.             err = DoInitContent(frHndl, window);
  355.             if (!err) {
  356.                 if (!((WindowPeek)window)->visible) {
  357.                     contRect = GetWindowContentRect(window);
  358.                     if (((WindowPeek)window)->spareFlag)
  359.                         userState = mDerefWStateData(window)->userState;
  360.                             /* Cache this.  ShowWindow offscreen messes it up.  We want to keep
  361.                             ** whatever it is because some other function may be tweeking stdState
  362.                             ** and userState so that window position and zoom state can be saved
  363.                             ** along with a document. */
  364.  
  365.                     MoveWindow(window, 16384, 16384, false);
  366.                         /* When an invisible window is added, it isn't the frontmost window.
  367.                         ** This causes a problem when we make it visible.  By moving it
  368.                         ** offscreen, we can make it visible without the user seeing that it
  369.                         ** isn't the top window. */
  370.  
  371.                     if (gPrintPage) {
  372.                         ShowWindow(window);                            /* Window now visible. */
  373.                         MoveWindow(window, 16384, 16384, true);        /* Window now on top.  */
  374.                     }    /* If we are printing, we want to leave the window offscreen, since we
  375.                         ** don't want it seen.  We do need a visible window when printing so
  376.                         ** PrintMonitor can get the document name. */
  377.  
  378.                     if (!gPrintPage) {
  379.                         if (attributes & kwVisible)
  380.                             ShowHide(window, true);
  381.                         CleanSendBehind(window, behind);
  382.                         MoveWindow(window, contRect.left, contRect.top, false);
  383.                     }
  384.  
  385.                     if (((WindowPeek)window)->spareFlag)
  386.                         mDerefWStateData(window)->userState = userState;
  387.                             /* The ShowWindow metrics we did cause the userState to change.  Put it
  388.                             ** back the way it was before we started messing around with the window. */
  389.  
  390.                     AdjustScrollBars(window);
  391.                 }
  392.             }
  393.         }
  394.         if (err) {
  395.             DisposeAnyWindow(window);
  396.             (*frHndl)->fileState.window = window = nil;
  397.         }
  398.     }
  399.     else err = gGetWindowErr;
  400.  
  401.     SetPort(oldPort);
  402.     if (retWindow)
  403.         *retWindow = window;
  404.  
  405.     return(err);
  406. }
  407.  
  408.  
  409.  
  410. /*****************************************************************************/
  411.  
  412.  
  413.  
  414. /* This function updates the window title to reflect the new document name.
  415. ** The new document name is stored in the fileState portion of the document.
  416. ** This is automatically set to 'Untitled # N' for new documents, and is
  417. ** updated when a user does a save-as.  If the window that is being opened
  418. ** should have the resource name, then set the new document name to an
  419. ** empty string prior to calling DoNewWindow.  When this is called by
  420. ** DoNewWindow, the SetWTitle will be suppressed. */
  421.  
  422. #pragma segment Window
  423. void    NewWindowTitle(WindowPtr window, StringPtr altTitle)
  424. {
  425.     FileRecHndl    frHndl;
  426.     Str255        wTitle;
  427.  
  428.     if (window) {
  429.         if (altTitle) {
  430.             pcpy(wTitle, altTitle);
  431.             SetWTitle(window, wTitle);
  432.         }
  433.         else {
  434.             frHndl = (FileRecHndl)GetWRefCon(window);
  435.             if (frHndl) {
  436.                 if (((WindowPeek)window)->windowKind >= 1000) {
  437.                     pcpy(wTitle, (*frHndl)->fileState.fss.name);
  438.                     if (*wTitle)
  439.                         SetWTitle(window, wTitle);
  440.                     else {
  441.                         if ((*frHndl)->fileState.refNum == kInvalRefNum) {
  442.                             GetWTitle(window, wTitle);
  443.                             if (*wTitle > 63) *wTitle = 63;
  444.                             pcpy((*frHndl)->fileState.fss.name, wTitle);
  445.                         }
  446.                     }
  447.                 }
  448.             }
  449.         }
  450.     }
  451. }
  452.  
  453.  
  454.  
  455. /*****************************************************************************/
  456.  
  457.  
  458.  
  459. /* Close all the windows.  This is called prior to quitting the application.
  460. ** This function returns true if all windows were closed.  The user may decide
  461. ** to abort a save, thus stopping the closing of the windows.  If the user
  462. ** does this, false will be returned, indicating that all windows were not
  463. ** closed after all. */
  464.  
  465. #pragma segment Window
  466. Boolean    DisposeAllWindows(void)
  467. {
  468.     WindowPtr    window;
  469.     FileRecHndl    frHndl;
  470.     long        attr;
  471.  
  472.     gCursorPtr = nil;        /* Force recalc of cursor. */
  473.  
  474.     for (window = nil;;) {
  475.  
  476.         if (!window)
  477.             window = FrontWindow();
  478.         else
  479.             window = (WindowPtr)(((WindowPeek)window)->nextWindow);
  480.  
  481.         if (!window) break;        /* All out of windows to get rid of. */
  482.  
  483.         if (!((WindowPeek)window)->visible) continue;
  484.             /* Invisible windows shouldn't be disposed of, since the user may cancel the quit,
  485.             ** and therefore the user will want windows around.  If a "hide on close" window
  486.             ** was closed, it was simply made invisible, so these windows are still actually
  487.             ** intact.  The user will have to show them again, but they still exist. */
  488.  
  489.         if (!IsDAWindow(window)) {
  490.             if (((WindowPeek)window)->windowKind >= 1000) {
  491.                 frHndl = (FileRecHndl)GetWRefCon(window);
  492.                 if (frHndl) {
  493.                     attr   = (*frHndl)->fileState.attributes;
  494.                     if (attr & kwIsPalette) continue;
  495.                         /* Closing of all of the windows may be stopped at a
  496.                         ** dirty document, so don't close the palettes. */
  497.                 }
  498.             }
  499.         }
  500.  
  501.         if (!DisposeOneWindow(window, kQuit)) return(false);
  502.             /* When DisposeOneWindow returns false, this means that the window
  503.             ** didn't close.  The only cause of this is if the window had a
  504.             ** document that needed saving, and the user cancelled the save.
  505.             ** If the windows succeed in getting closed, then we are
  506.             ** returned true. */
  507.  
  508.         window = nil;
  509.             /* The close of a window may have caused other window to close, so
  510.             ** start looking at windows from the beginning of the list.  This
  511.             ** guarantees that we are always looking at valid window records. */
  512.     }
  513.  
  514.     return(true);
  515. }
  516.  
  517.  
  518.  
  519. /*****************************************************************************/
  520.  
  521.  
  522.  
  523. /* Closes one window.  This window may be an application window, or it may be
  524. ** a system window.  If it is an application window, it may have a document
  525. ** that needs saving. */
  526.  
  527. #pragma segment Window
  528. Boolean    DisposeOneWindow(WindowPtr window, short saveMode)
  529. {
  530.     FileRecHndl    frHndl;
  531.     long        attr;
  532.     OSErr        err;
  533.  
  534.     gCursorPtr = nil;        /* Force recalc of cursor. */
  535.  
  536.     if (window) {
  537.         if (!IsDAWindow(window)) {
  538.             /* First, if the window is an application window, try saving
  539.             ** the document.  Remember that the user may cancel the save. */
  540.  
  541.             if (((WindowPeek)window)->windowKind >= 1000) {
  542.                 frHndl = (FileRecHndl)GetWRefCon(window);
  543.                 if (frHndl) {
  544.  
  545.                     attr = (*frHndl)->fileState.attributes;
  546.                     if (attr & kwHideOnClose) {
  547.                         if (gHideWindowProc) {
  548.                             err = (*gHideWindowProc)(frHndl, window);
  549.                             if (err)
  550.                                 return(false);
  551.                         }
  552.                         HideWindow(window);
  553.                         HiliteWindows();
  554.                         WindowGoneFixup(window);
  555.                         return(true);
  556.                     }
  557.  
  558.                     if (!((*frHndl)->fileState.attributes & kwRuntimeOnlyDoc)) {
  559.                         if (IsAppWindow(window)) {
  560.                             err = SaveDocument(frHndl, window, saveMode);
  561.                             if (err) {
  562.                                 if (err != userCanceledErr) {
  563.                                     gDialogErr = err;
  564.                                     NewDocumentWindow(nil, 'ERR#', false);
  565.                                 }
  566.                                 return(false);
  567.                             }        /* Stop closing windows on error or user cancel. */
  568.                         }
  569.                     }
  570.  
  571.                     err = DoFreeWindow(frHndl, window);
  572.                     if (err) return(false);
  573.  
  574.                     DisposeDocument(frHndl);
  575.                         /* If everything is cool, dispose of the document. */
  576.                 }
  577.             }
  578.         }
  579.  
  580.         DisposeAnyWindow(window);
  581.         HiliteWindows();
  582.         WindowGoneFixup(window);
  583.             /* Give the application a chance to do any related tasks. */
  584.     }
  585.  
  586.     return(true);
  587. }
  588.  
  589.  
  590.  
  591. /*****************************************************************************/
  592.  
  593.  
  594.  
  595. #pragma segment Window
  596. WindowPtr    SetFilePort(FileRecHndl frHndl)
  597. {
  598.     WindowPtr    oldPort;
  599.  
  600.     GetPort(&oldPort);
  601.     if (frHndl)
  602.         SetPort((*frHndl)->fileState.window);
  603.     return(oldPort);
  604. }
  605.  
  606.  
  607.  
  608. /*****************************************************************************/
  609.  
  610.  
  611.  
  612. #pragma segment Window
  613. void    DoResizeWindow(WindowPtr window, short oldh, short oldv)
  614. {
  615.     FileRecHndl        frHndl;
  616.     WindowPtr        oldPort;
  617.     long            attributes;
  618.     Boolean            growIconSpace;
  619.     Rect            portRct, rct;
  620.     ControlHandle    hScroll, vScroll;
  621.     RgnHandle        updateRgn;
  622.     short            i;
  623.  
  624.     gCursorPtr = nil;        /* Force recalc of cursor. */
  625.  
  626.     if (!window)                                     return;
  627.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  628.  
  629.     oldPort       = SetFilePort(frHndl);
  630.     attributes    = (*frHndl)->fileState.attributes;
  631.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  632.         /* growIconSpace true if window has grow icon or a blank space for one. */
  633.  
  634.     SetOrigin(0, 0);
  635.     portRct = window->portRect;
  636.  
  637.     if (growIconSpace) {
  638.         rct.left = (rct.right  = oldh) - 15;
  639.         rct.top  = (rct.bottom = oldv) - 15;
  640.         EraseRect(&rct);
  641.         InvalRect(&rct);
  642.         rct = portRct;
  643.         rct.left = rct.right  - 15;
  644.         rct.top  = rct.bottom - 15;
  645.         EraseRect(&rct);
  646.     }
  647.  
  648.     SetOrigin(0, -16384);
  649.     hScroll = (*frHndl)->fileState.hScroll;
  650.     if (hScroll) {
  651.         HideControl(hScroll);
  652.         rct = (*hScroll)->contrlRect;
  653.         MoveControl(hScroll, rct.left, portRct.bottom - 15 - 16384);
  654.         SizeControl(hScroll, rct.right - rct.left + (portRct.right - portRct.left - oldh), 16);
  655.     }
  656.     vScroll = (*frHndl)->fileState.vScroll;
  657.     if (vScroll) {
  658.         HideControl(vScroll);
  659.         rct = (*vScroll)->contrlRect;
  660.         MoveControl(vScroll, portRct.right - 15, rct.top);
  661.         SizeControl(vScroll, 16, rct.bottom - rct.top + (portRct.bottom - portRct.top - oldv));
  662.     }
  663.  
  664.     i = (*frHndl)->fileState.hScrollIndent;
  665.     if (i) {
  666.         rct       = window->portRect;
  667.         rct.right = --i;
  668.         rct.top   = rct.bottom - 15;
  669.         InvalRect(&rct);
  670.         rct.bottom = window->portRect.top + oldv;
  671.         rct.top    = rct.bottom - 15;
  672.         EraseRect(&rct);
  673.         InvalRect(&rct);
  674.     }
  675.  
  676.     i = (*frHndl)->fileState.vScrollIndent;
  677.     if (i) {
  678.         rct        = window->portRect;
  679.         rct.bottom = --i;
  680.         rct.left   = rct.right - 15;
  681.         InvalRect(&rct);
  682.         rct.right  = window->portRect.left + oldh;
  683.         rct.left   = rct.right - 15;
  684.         EraseRect(&rct);
  685.         InvalRect(&rct);
  686.     }
  687.  
  688.     AdjustScrollBars(window);
  689.  
  690.     if (hScroll)
  691.         ShowControl(hScroll);
  692.     if (vScroll)
  693.         ShowControl(vScroll);
  694.  
  695.     SetOrigin(0, 0);
  696.     if (attributes & kwGrowIcon)
  697.         DoDrawGrowIcon(window, false, false);
  698.  
  699.     BeginContent(window);
  700.     DoResizeContent(window, oldh, oldv);
  701.     updateRgn = NewRgn();
  702.     CopyRgn(((WindowPeek)window)->updateRgn, updateRgn);
  703.     EndContent(window);
  704.     UnionRgn(updateRgn, ((WindowPeek)window)->updateRgn, ((WindowPeek)window)->updateRgn);
  705.     DisposeRgn(updateRgn);
  706.  
  707.     SetPort(oldPort);
  708. }
  709.  
  710.  
  711.  
  712. /*****************************************************************************/
  713.  
  714.  
  715.  
  716. /* This function returns the difference between the old window size and the new window
  717. ** size.  Pass in the old window size, and this function looks up the current size,
  718. ** gets the difference, and returns it. */
  719.  
  720. #pragma segment Window
  721. void    GetWindowChange(WindowPtr window, short oldh, short oldv, short *dx, short *dy)
  722. {
  723.     *dx = (window->portRect.right  - window->portRect.left) - oldh;
  724.     *dy = (window->portRect.bottom - window->portRect.top)  - oldv;
  725.  
  726. }
  727.  
  728.  
  729.  
  730. /*****************************************************************************/
  731.  
  732.  
  733.  
  734. #pragma segment Window
  735. void    DoUpdateSeparate(WindowPtr window, RgnHandle *contRgn, RgnHandle *frameRgn)
  736. {
  737.     RgnHandle    urgn, wrgn;
  738.  
  739.     *contRgn = *frameRgn = nil;
  740.     if (!window) return;
  741.  
  742.     urgn = DoCalcFrameRgn(window);
  743.     wrgn = NewRgn();
  744.  
  745.     DiffRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  746.     if (!EmptyRgn(wrgn)) {
  747.         *contRgn = wrgn;
  748.         wrgn = NewRgn();
  749.     }
  750.     SectRgn(((WindowPeek)window)->updateRgn, urgn, wrgn);
  751.  
  752.     if (!EmptyRgn(wrgn))
  753.         *frameRgn = wrgn;
  754.     else
  755.         DisposeRgn(wrgn);
  756.  
  757.     DisposeRgn(urgn);
  758. }
  759.  
  760.  
  761.  
  762. /*****************************************************************************/
  763.  
  764.  
  765.  
  766. #pragma segment Window
  767. void    BeginContent(WindowPtr window)
  768. {
  769.     RgnHandle    updateRgn, frameRgn;
  770.     Point        contOrg;
  771.  
  772.     if (!gBeginUpdateNested++) {
  773.         GetPort(&gOldPort);
  774.         CopyRgn(updateRgn = ((WindowPeek)window)->updateRgn, gKeepUpdateRgn = NewRgn());
  775.         frameRgn = DoCalcFrameRgn(window);
  776.         DiffRgn(((WindowPeek)window)->contRgn, frameRgn, updateRgn);
  777.         DisposeRgn(frameRgn);
  778.         BeginUpdate(window);
  779.     }
  780.     SetPort(window);
  781.     GetContentOrigin(window, &contOrg);
  782.     SetOrigin(contOrg.h, contOrg.v);
  783. }
  784.  
  785.  
  786.  
  787. /*****************************************************************************/
  788.  
  789.  
  790.  
  791. #pragma segment Window
  792. void    EndContent(WindowPtr window)
  793. {
  794.     if (gBeginUpdateNested) {
  795.         if (!--gBeginUpdateNested) {
  796.             EndUpdate(window);
  797.             if (gKeepUpdateRgn) {
  798.                 UnionRgn(gKeepUpdateRgn, ((WindowPeek)window)->updateRgn, ((WindowPeek)window)->updateRgn);
  799.                 DisposeRgn(gKeepUpdateRgn);
  800.                 SetPort(gOldPort);
  801.                 gKeepUpdateRgn = nil;
  802.             }
  803.         }
  804.     }
  805. }
  806.  
  807.  
  808.  
  809. /*****************************************************************************/
  810.  
  811.  
  812.  
  813. #pragma segment Window
  814. void    BeginFrame(WindowPtr window)
  815. {
  816.     RgnHandle    updateRgn, frameRgn, scrollRgn;
  817.  
  818.     if (!gBeginUpdateNested++) {
  819.         GetPort(&gOldPort);
  820.         CopyRgn(updateRgn = ((WindowPeek)window)->updateRgn, gKeepUpdateRgn = NewRgn());
  821.         frameRgn  = DoCalcFrameRgn(window);
  822.         scrollRgn = DoCalcScrollRgn(window);
  823.         DiffRgn(frameRgn, scrollRgn, frameRgn);
  824.         DisposeRgn(scrollRgn);
  825.         SectRgn(((WindowPeek)window)->contRgn, frameRgn, updateRgn);
  826.         DisposeRgn(frameRgn);
  827.         BeginUpdate(window);
  828.     }
  829.     SetPort(window);
  830.     SetOrigin(-16384, 0);
  831. }
  832.  
  833.  
  834.  
  835. /*****************************************************************************/
  836.  
  837.  
  838.  
  839. #pragma segment Window
  840. void    EndFrame(WindowPtr window)
  841. {
  842.     EndContent(window);
  843. }
  844.  
  845.  
  846.  
  847. /*****************************************************************************/
  848.  
  849.  
  850.  
  851. #pragma segment Window
  852. void    AdjustScrollBars(WindowPtr window)
  853. {
  854.     FileRecHndl            frHndl;
  855.     WindowPtr            oldPort;
  856.     ControlHandle        hScroll, vScroll;
  857.     Rect                portRct;
  858.     Point                keepOrg;
  859.     short                h, v, maxVal, val;
  860.     DocScrollBarProc    proc;
  861.  
  862.     if (!window)                                     return;
  863.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  864.  
  865.     oldPort = SetFilePort(frHndl);
  866.     portRct = window->portRect;
  867.  
  868.     keepOrg.h = portRct.left;
  869.     keepOrg.v = portRct.top;
  870.  
  871.     portRct.left += (*frHndl)->fileState.leftSidebar;
  872.     portRct.top  += (*frHndl)->fileState.topSidebar;
  873.  
  874.     hScroll = (*frHndl)->fileState.hScroll;
  875.     vScroll = (*frHndl)->fileState.vScroll;
  876.  
  877.     SetOrigin(0, -16384);
  878.  
  879.     if ((maxVal = (*frHndl)->d.doc.fhInfo.hDocSize) > 0) {
  880.         h = portRct.right - portRct.left;
  881.         if (vScroll)
  882.             h -= 15;
  883.         maxVal -= h;
  884.         if (maxVal < 0)
  885.             maxVal = 0;
  886.         if (hScroll) {
  887.             proc = (DocScrollBarProc)GetControlReference(hScroll);
  888.             if (proc)
  889.                 (*proc)(frHndl, hScroll, kscrollHAdjust, h);
  890.             else {
  891.                 if (maxVal < (val = GetControlValue(hScroll)))
  892.                     maxVal = val;
  893.                 if ((*hScroll)->contrlMax != maxVal) {
  894.                     (*hScroll)->contrlMax = maxVal;
  895.                     DoDraw1Control(hScroll, true);
  896.                 }
  897.                 h -= (val = (*frHndl)->fileState.hArrowVal);
  898.                 if (h < val)
  899.                     h = val;
  900.                 (*frHndl)->fileState.hPageVal = h;
  901.             }
  902.         }
  903.     }
  904.  
  905.     if ((maxVal = (*frHndl)->d.doc.fhInfo.vDocSize) > 0) {
  906.         v = portRct.bottom - portRct.top;
  907.         if (hScroll)
  908.             v -= 15;
  909.         maxVal -= v;
  910.         if (maxVal < 0)
  911.             maxVal = 0;
  912.         if (vScroll) {
  913.             proc = (DocScrollBarProc)GetControlReference(vScroll);
  914.             if (proc)
  915.                 (*proc)(frHndl, vScroll, kscrollVAdjust, v);
  916.             else {
  917.                 if (maxVal < (val = GetControlValue(vScroll)))
  918.                     maxVal = val;
  919.                 if ((*vScroll)->contrlMax != maxVal) {
  920.                     (*vScroll)->contrlMax = maxVal;
  921.                     DoDraw1Control(vScroll, true);
  922.                 }
  923.                 v -= (val = (*frHndl)->fileState.vArrowVal);
  924.                 if (v < val)
  925.                     v = val;
  926.                 (*frHndl)->fileState.vPageVal = v;
  927.             }
  928.         }
  929.     }
  930.  
  931.     SetOrigin(keepOrg.h, keepOrg.v);
  932.     SetPort(oldPort);
  933. }
  934.  
  935.  
  936.  
  937. /*****************************************************************************/
  938.  
  939.  
  940.  
  941. #pragma segment Window
  942. void    GetContentOrigin(WindowPtr window, Point *contOrg)
  943. {
  944.     FileRecHndl            frHndl;
  945.     ControlHandle        ctl;
  946.     DocScrollBarProc    proc;
  947.  
  948.     contOrg->h = contOrg->v = 0;
  949.  
  950.     if (window) {
  951.         if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  952.         ctl = (*frHndl)->fileState.hScroll;
  953.         if (ctl) {
  954.             contOrg->h = GetControlValue(ctl);
  955.             proc = (DocScrollBarProc)GetControlReference(ctl);
  956.             if (proc)
  957.                 contOrg->h = (*proc)(frHndl, ctl, kscrollGetHOrigin, 0);
  958.         }
  959.         ctl = (*frHndl)->fileState.vScroll;
  960.         if (ctl) {
  961.             contOrg->v = GetControlValue(ctl);
  962.             proc = (DocScrollBarProc)GetControlReference(ctl);
  963.             if (proc)
  964.                 contOrg->v = (*proc)(frHndl, ctl, kscrollGetVOrigin, 0);
  965.         }
  966.         contOrg->h -= (*frHndl)->fileState.leftSidebar;
  967.         contOrg->v -= (*frHndl)->fileState.topSidebar;
  968.     }
  969. }
  970.  
  971.  
  972.  
  973. /*****************************************************************************/
  974.  
  975.  
  976.  
  977. #pragma segment Window
  978. void    SetContentOrigin(WindowPtr window, long newh, long newv)
  979. {
  980.     FileRecHndl        frHndl;
  981.     WindowPtr        oldPort;
  982.     ControlHandle    hScroll, vScroll;
  983.     short            topSide, leftSide, max, dh, dv;
  984.     Point            old, contOrg;
  985.     RgnHandle        updateRgn;
  986.     Rect            contRct;
  987.  
  988.     gCursorPtr = nil;        /* Force recalc of cursor. */
  989.  
  990.     if (!window)                                     return;
  991.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  992.  
  993.     oldPort = SetFilePort(frHndl);
  994.     hScroll = (*frHndl)->fileState.hScroll;
  995.     vScroll = (*frHndl)->fileState.vScroll;
  996.     GetContentOrigin(window, &old);
  997.     GetContentRect(window, &contRct);
  998.  
  999.     SetOrigin(0, -16384);
  1000.     topSide  = (*frHndl)->fileState.topSidebar;
  1001.     leftSide = (*frHndl)->fileState.leftSidebar;
  1002.  
  1003.     if (!hScroll)
  1004.         newh = kwNoChange;
  1005.     if (newh != kwNoChange) {
  1006.         if (newh != kwBotScroll)
  1007.             newh += leftSide;
  1008.         if (newh < 0)
  1009.             newh = 0;
  1010.         if (newh > (max = GetControlMaximum(hScroll)))
  1011.             newh = max;
  1012.         if ((*hScroll)->contrlValue != newh) {
  1013.             (*hScroll)->contrlValue = newh;
  1014.             DoDraw1Control(hScroll, true);
  1015.         }
  1016.         newh -= leftSide;
  1017.     }
  1018.  
  1019.     if (!vScroll)
  1020.         newv = kwNoChange;
  1021.     if (newv != kwNoChange) {
  1022.         if (newv != kwBotScroll)
  1023.             newv += topSide;
  1024.         if (newv < 0)
  1025.             newv = 0;
  1026.         if (newv > (max = GetControlMaximum(vScroll)))
  1027.             newv = max;
  1028.         if ((*vScroll)->contrlValue != newv) {
  1029.             (*vScroll)->contrlValue = newv;
  1030.             DoDraw1Control(vScroll, true);
  1031.         }
  1032.         newv -= topSide;
  1033.     }
  1034.  
  1035.     AdjustScrollBars(window);
  1036.  
  1037.     dh = dv = 0;
  1038.     if (newh != kwNoChange)
  1039.         dh = old.h - newh;
  1040.     if (newv != kwNoChange)
  1041.         dv = old.v - newv;
  1042.  
  1043.     BeginContent(window);
  1044.     ScrollRect(&(window->portRect), dh, dv, updateRgn = NewRgn());
  1045.     EndContent(window);
  1046.  
  1047.     OffsetRgn(((WindowPeek)window)->updateRgn, dh, dv);
  1048.         /* We want to add the scrolled-in area into the updateRgn.  We
  1049.         ** also want to keep the old area.  The old update area is
  1050.         ** no longer mapped to the same location, due to the scroll,
  1051.         ** so offset it by the amount scrolled.  Once it is offset, we
  1052.         ** can add our new update portion to the updateRgn. */
  1053.  
  1054.     GetContentOrigin(window, &contOrg);
  1055.     SetOrigin(contOrg.h, contOrg.v);
  1056.     InvalRgn(updateRgn);
  1057.     DisposeRgn(updateRgn);
  1058.  
  1059.     SetOrigin(old.h, old.v);
  1060.     SetPort(oldPort);                /* Put things back the way we found them. */
  1061.  
  1062.     DoScrollFrame(window, dh, dv);    /* There may be changes in the frame due to scrolling. */
  1063.  
  1064.     DoSetCursor(nil);                /* Cursor region may be invalid due to
  1065.                                     ** content being scrolled.  Force it to
  1066.                                     ** be recalculated. */
  1067. }
  1068.  
  1069.  
  1070.  
  1071. /*****************************************************************************/
  1072.  
  1073.  
  1074.  
  1075. #pragma segment Window
  1076. void    GetContentRect(WindowPtr window, Rect *contRct)
  1077. {
  1078.     FileRecHndl        frHndl;
  1079.  
  1080.     SetRect(contRct, 0, 0, 0, 0);
  1081.  
  1082.     if (window) {
  1083.         if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  1084.         *contRct = window->portRect;
  1085.         if ((*frHndl)->fileState.hScroll)
  1086.             contRct->bottom -= 15;
  1087.         if ((*frHndl)->fileState.vScroll)
  1088.             contRct->right  -= 15;
  1089.         contRct->top  += (*frHndl)->fileState.topSidebar;
  1090.         contRct->left += (*frHndl)->fileState.leftSidebar;
  1091.     }
  1092. }
  1093.  
  1094.  
  1095.  
  1096. /*****************************************************************************/
  1097.  
  1098.  
  1099.  
  1100. #pragma segment Window
  1101. void    SetDocSize(FileRecHndl frHndl, long hSize, long vSize)
  1102. {
  1103.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1104.  
  1105.     if (frHndl) {
  1106.         if (hSize >= 0)
  1107.             (*frHndl)->d.doc.fhInfo.hDocSize = hSize;
  1108.         if (vSize >= 0)
  1109.             (*frHndl)->d.doc.fhInfo.vDocSize = vSize;
  1110.         AdjustScrollBars((*frHndl)->fileState.window);
  1111.     }
  1112. }
  1113.  
  1114.  
  1115.  
  1116. /*****************************************************************************/
  1117.  
  1118.  
  1119.  
  1120. #pragma segment Window
  1121. void    SetSidebarSize(FileRecHndl frHndl, short newLeft, short newTop)
  1122. {
  1123.     WindowPtr            oldPort, window;
  1124.     Rect                portRct, rct;
  1125.     Point                contOrg;
  1126.     short                oldLeft, oldTop, dh, dv;
  1127.     ControlHandle        ctl;
  1128.     RgnHandle            updateRgn;
  1129.     DrawFrameProcPtr    proc;
  1130.  
  1131.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1132.  
  1133.     window = (*frHndl)->fileState.window;
  1134.     if (window) {
  1135.         oldPort = SetFilePort(frHndl);
  1136.         portRct = window->portRect;
  1137.         SetOrigin(0, -16384);        /* Prepare to modify (redraw) document scrollbars. */
  1138.     }
  1139.  
  1140.     oldLeft = (*frHndl)->fileState.leftSidebar;
  1141.     oldTop  = (*frHndl)->fileState.topSidebar;
  1142.  
  1143.     dh = 0;
  1144.     if (newLeft != kwNoChange) {
  1145.         ctl = (*frHndl)->fileState.hScroll;
  1146.         if (ctl) {
  1147.             HideControl(ctl);
  1148.             rct = (*ctl)->contrlRect;
  1149.             rct.left += (newLeft - oldLeft);
  1150.             MoveControl(ctl, rct.left, rct.top);
  1151.             SizeControl(ctl, rct.right - rct.left, 16);
  1152.             ShowControl(ctl);
  1153.         }
  1154.         dh = newLeft - oldLeft;
  1155.     }
  1156.  
  1157.     dv = 0;
  1158.     if (newTop != kwNoChange) {
  1159.         ctl = (*frHndl)->fileState.vScroll;
  1160.         if (ctl) {
  1161.             HideControl(ctl);
  1162.             rct = (*ctl)->contrlRect;
  1163.             rct.top += (newTop - oldTop);
  1164.             MoveControl(ctl, rct.left, rct.top);
  1165.             SizeControl(ctl, 16, rct.bottom - rct.top);
  1166.             ShowControl(ctl);
  1167.         }
  1168.         dv = newTop - oldTop;
  1169.     }
  1170.  
  1171.     if (dh < 0)
  1172.         (*frHndl)->fileState.leftSidebar = newLeft;
  1173.     if (dv < 0)
  1174.         (*frHndl)->fileState.topSidebar  = newTop;
  1175.  
  1176.     if (window) {
  1177.         BeginContent(window);
  1178.         ScrollRect(&(window->portRect), dh, dv, updateRgn = NewRgn());
  1179.         EndContent(window);
  1180.     }
  1181.  
  1182.     if (dh)
  1183.         (*frHndl)->fileState.leftSidebar = newLeft;
  1184.     if (dv)
  1185.         (*frHndl)->fileState.topSidebar  = newTop;
  1186.  
  1187.     if (window) {
  1188.         AdjustScrollBars(window);
  1189.  
  1190.         proc = (*frHndl)->fileState.drawFrameProc;
  1191.         if (proc) {
  1192.             SetOrigin(-16384, 0);
  1193.             (*proc)(frHndl, window, false);        /* Draw the application's portion of the frame. */
  1194.         }
  1195.  
  1196.         OffsetRgn(((WindowPeek)window)->updateRgn, dh, dv);
  1197.             /* We want to add the scrolled-in area into the updateRgn.  We
  1198.             ** also want to keep the old area.  The old update area is
  1199.             ** no longer mapped to the same location, due to the scroll,
  1200.             ** so offset it by the amount scrolled.  Once it is offset, we
  1201.             ** can add our new update portion to the updateRgn. */
  1202.         GetContentOrigin(window, &contOrg);
  1203.         SetOrigin(contOrg.h, contOrg.v);
  1204.         InvalRgn(updateRgn);
  1205.         DisposeRgn(updateRgn);
  1206.  
  1207.         SetOrigin(portRct.left, portRct.top);
  1208.         SetPort(oldPort);
  1209.  
  1210.         DoScrollFrame(window, dh, dv);        /* There may be changes in the frame due to scrolling. */
  1211.     }
  1212. }
  1213.  
  1214.  
  1215.  
  1216. /*****************************************************************************/
  1217.  
  1218.  
  1219.  
  1220. #pragma segment Window
  1221. void    SetScrollIndentSize(FileRecHndl frHndl, short newh, short newv)
  1222. {
  1223.     WindowPtr            oldPort, window;
  1224.     Rect                portRct, rct;
  1225.     short                oldh, oldv;
  1226.     ControlHandle        ctl;
  1227.     DrawFrameProcPtr    proc;
  1228.  
  1229.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1230.  
  1231.     oldPort = SetFilePort(frHndl);
  1232.     GetPort(&window);
  1233.     portRct = window->portRect;
  1234.     SetOrigin(0, -16384);
  1235.  
  1236.     oldh = (*frHndl)->fileState.hScrollIndent;
  1237.     oldv = (*frHndl)->fileState.vScrollIndent;
  1238.  
  1239.     if (newh != kwNoChange) {
  1240.         ctl = (*frHndl)->fileState.hScroll;
  1241.         if (ctl) {
  1242.             HideControl(ctl);
  1243.             rct = (*ctl)->contrlRect;
  1244.             rct.left += (newh - oldh);
  1245.             MoveControl(ctl, rct.left, rct.top);
  1246.             SizeControl(ctl, rct.right - rct.left, 16);
  1247.             ShowControl(ctl);
  1248.         }
  1249.         (*frHndl)->fileState.hScrollIndent = newh;
  1250.     }
  1251.  
  1252.     if (newv != kwNoChange) {
  1253.         ctl = (*frHndl)->fileState.vScroll;
  1254.         if (ctl) {
  1255.             HideControl(ctl);
  1256.             rct = (*ctl)->contrlRect;
  1257.             rct.top += (newv - oldv);
  1258.             MoveControl(ctl, rct.left, rct.top);
  1259.             SizeControl(ctl, 16, rct.bottom - rct.top);
  1260.             ShowControl(ctl);
  1261.         }
  1262.         (*frHndl)->fileState.vScrollIndent = newv;
  1263.     }
  1264.  
  1265.     proc = (*frHndl)->fileState.drawFrameProc;
  1266.     if (proc) {
  1267.         SetOrigin(-16384, 0);
  1268.         (*proc)(frHndl, window, false);        /* Draw the application's portion of the frame. */
  1269.     }
  1270.  
  1271.     SetOrigin(portRct.left, portRct.top);
  1272.     SetPort(oldPort);
  1273. }
  1274.  
  1275.  
  1276.  
  1277. /*****************************************************************************/
  1278.  
  1279.  
  1280.  
  1281. #pragma segment Window
  1282. FileRecHndl    GetNextDocument(WindowPtr window, OSType sftype)
  1283. {
  1284.     if (!(window = GetNextWindow(window, sftype))) return(nil);
  1285.     if (IsDAWindow(window))                           return(nil);
  1286.  
  1287.     return((FileRecHndl)GetWRefCon(window));
  1288. }
  1289.  
  1290.  
  1291.  
  1292. /*****************************************************************************/
  1293.  
  1294.  
  1295.  
  1296. #pragma segment Window
  1297. WindowPtr    GetNextWindow(WindowPtr window, OSType sftype)
  1298. {
  1299.     WindowPeek    wpeek;
  1300.     FileRecHndl    frHndl;
  1301.  
  1302.     if (window == (WindowPtr)-1)
  1303.         window = nil;
  1304.  
  1305.     if (!window)
  1306.         wpeek = LMGetWindowList();
  1307.     else
  1308.         wpeek = ((WindowPeek)window)->nextWindow;
  1309.  
  1310.     for (; wpeek; wpeek = wpeek->nextWindow) {
  1311.  
  1312.         if (IsDAWindow((WindowPtr)wpeek))
  1313.             if (!sftype)
  1314.                 return((WindowPtr)wpeek);
  1315.  
  1316.         if (wpeek->windowKind < 1000) continue;
  1317.  
  1318.         if (!sftype) break;
  1319.             /* Request is for any window.  We have a window, so break. */
  1320.  
  1321.         frHndl = (FileRecHndl)GetWRefCon((WindowPtr)wpeek);
  1322.         if (!frHndl) continue;
  1323.  
  1324.         if ((*frHndl)->fileState.sfType == sftype) break;        /* Bingo. */
  1325.             /* The sfType field is the first 4 bytes in the refcon handle.  If you don't
  1326.             ** want to use the application framework completely, but you still want this
  1327.             ** function, then all you have to do is place an identifier in the first 4
  1328.             ** bytes of the refcon handle. */
  1329.     }
  1330.  
  1331.     return((WindowPtr)wpeek);
  1332. }
  1333.  
  1334.  
  1335.  
  1336. /*****************************************************************************/
  1337.  
  1338.  
  1339.  
  1340. #pragma segment Window
  1341. WindowPtr    GetPreviousWindow(WindowPtr window)
  1342. {
  1343.     WindowPeek    wpeek;
  1344.     WindowPtr    lastWindow;
  1345.  
  1346.     if (window == (WindowPtr)-1) return((WindowPtr)-1);
  1347.     wpeek = LMGetWindowList();
  1348.  
  1349.     for (lastWindow = (WindowPtr)-1; wpeek; wpeek = wpeek->nextWindow) {
  1350.         if (window == (WindowPtr)wpeek) break;
  1351.         lastWindow = (WindowPtr)wpeek;
  1352.     }
  1353.  
  1354.     return(lastWindow);
  1355. }
  1356.  
  1357.  
  1358.  
  1359. /*****************************************************************************/
  1360.  
  1361.  
  1362.  
  1363. #pragma segment Window
  1364. void    DoZoomWindow(WindowPtr window, EventRecord *event, short zoomDir)
  1365. {
  1366.     Boolean        doit;
  1367.     Rect        old;
  1368.     FileRecHndl    frHndl;
  1369.     short        hDocSize, vDocSize;
  1370.  
  1371.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1372.  
  1373.     if (!window)                                     return;
  1374.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return;
  1375.  
  1376.     doit = true;
  1377.     if (event)
  1378.         doit = TrackBox(window, event->where, zoomDir);
  1379.  
  1380.     if (doit) {
  1381.         old       = GetWindowContentRect(window);
  1382.         hDocSize  = (*frHndl)->d.doc.fhInfo.hDocSize;
  1383.         hDocSize += (*frHndl)->fileState.leftSidebar;
  1384.         if ((*frHndl)->fileState.vScroll)
  1385.             hDocSize += 15;
  1386.         vDocSize  = (*frHndl)->d.doc.fhInfo.vDocSize;
  1387.         vDocSize += (*frHndl)->fileState.topSidebar;
  1388.         if ((*frHndl)->fileState.hScroll)
  1389.             vDocSize += 15;
  1390.  
  1391.         if (hDocSize < (*frHndl)->fileState.windowSizeBounds.left)
  1392.             hDocSize = (*frHndl)->fileState.windowSizeBounds.left;
  1393.         if (vDocSize < (*frHndl)->fileState.windowSizeBounds.top)
  1394.             vDocSize = (*frHndl)->fileState.windowSizeBounds.top;
  1395.  
  1396.         ZoomToWindowDevice(window, hDocSize, vDocSize, zoomDir, false);
  1397.         DoResizeWindow(window, old.right - old.left, old.bottom - old.top);
  1398.     }
  1399. }
  1400.  
  1401.  
  1402.  
  1403. /*****************************************************************************/
  1404. /*****************************************************************************/
  1405.  
  1406.  
  1407.  
  1408. #pragma segment Window
  1409. RgnHandle    DoCalcFrameRgn(WindowPtr window)
  1410. {
  1411.     FileRecHndl            frHndl;
  1412.     WindowPtr            oldPort;
  1413.     RgnHandle            urgn, wrgn;
  1414.     short                i;
  1415.     Rect                rct;
  1416.     Point                l2g;
  1417.     CalcFrameRgnProcPtr    proc;
  1418.  
  1419.     urgn = NewRgn();
  1420.     if (!window)                                     return(urgn);
  1421.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return(urgn);
  1422.  
  1423.     oldPort = SetFilePort(frHndl);
  1424.     SetOrigin(0, 0);
  1425.  
  1426.     proc = (*frHndl)->fileState.calcFrameRgnProc;
  1427.     if (proc)
  1428.         (*proc)(frHndl, window, urgn);
  1429.  
  1430.     wrgn = NewRgn();
  1431.     for (i = 0; i < 2; ++i) {
  1432.         rct = window->portRect;
  1433.         if (i)
  1434.             rct.bottom = (*frHndl)->fileState.topSidebar;
  1435.         else
  1436.             rct.right  = (*frHndl)->fileState.leftSidebar;
  1437.         RectRgn(wrgn, &rct);
  1438.         UnionRgn(urgn, wrgn, urgn);
  1439.     }
  1440.     DisposeRgn(wrgn);
  1441.  
  1442.     l2g.h = l2g.v = 0;
  1443.     LocalToGlobal(&l2g);
  1444.     OffsetRgn(urgn, l2g.h, l2g.v);
  1445.  
  1446.     wrgn = DoCalcScrollRgn(window);
  1447.     UnionRgn(urgn, wrgn, urgn);
  1448.     DisposeRgn(wrgn);
  1449.  
  1450.     SetPort(oldPort);
  1451.     return(urgn);
  1452. }
  1453.  
  1454.  
  1455.  
  1456. /*****************************************************************************/
  1457.  
  1458.  
  1459.  
  1460. #pragma segment Window
  1461. RgnHandle    DoCalcScrollRgn(WindowPtr window)
  1462. {
  1463.     FileRecHndl            frHndl;
  1464.     WindowPtr            oldPort;
  1465.     RgnHandle            urgn, wrgn;
  1466.     short                i;
  1467.     long                attributes;
  1468.     Boolean                growIconSpace;
  1469.     Rect                rct;
  1470.     Point                l2g;
  1471.     ControlHandle        ctl;
  1472.  
  1473.     urgn = NewRgn();
  1474.     if (!window) return(urgn);
  1475.     if (!window)                                     return(urgn);
  1476.     if (!(frHndl = (FileRecHndl)GetWRefCon(window))) return(urgn);
  1477.  
  1478.     oldPort = SetFilePort(frHndl);
  1479.     SetOrigin(0, 0);
  1480.  
  1481.     attributes    = (*frHndl)->fileState.attributes;
  1482.     growIconSpace = (attributes & (kwGrowIcon | (kwHScrollLessGrow - kwHScroll) | (kwVScrollLessGrow - kwVScroll)));
  1483.         /* growIconSpace true if window has grow icon or a blank space for one. */
  1484.  
  1485.     wrgn = NewRgn();
  1486.     if (growIconSpace) {
  1487.         rct = window->portRect;
  1488.         rct.left = rct.right  - 15;
  1489.         rct.top  = rct.bottom - 15;
  1490.         RectRgn(wrgn, &rct);
  1491.         UnionRgn(urgn, wrgn, urgn);
  1492.     }
  1493.     for (i = 0; i < 2; ++i) {
  1494.         ctl = (i) ? (*frHndl)->fileState.vScroll : (*frHndl)->fileState.hScroll;
  1495.         if (ctl) {
  1496.             rct = (*ctl)->contrlRect;
  1497.             if (i)
  1498.                 rct.top  -= (*frHndl)->fileState.vScrollIndent;
  1499.             else
  1500.                 rct.left -= (*frHndl)->fileState.hScrollIndent;
  1501.             OffsetRect(&rct, 0, 16384);
  1502.             RectRgn(wrgn, &rct);
  1503.             UnionRgn(urgn, wrgn, urgn);
  1504.         }
  1505.     }
  1506.     DisposeRgn(wrgn);
  1507.  
  1508.     l2g.h = l2g.v = 0;
  1509.     LocalToGlobal(&l2g);
  1510.     OffsetRgn(urgn, l2g.h, l2g.v);
  1511.  
  1512.     SetPort(oldPort);
  1513.     return(urgn);
  1514. }
  1515.  
  1516.  
  1517.  
  1518. /*****************************************************************************/
  1519.  
  1520.  
  1521.  
  1522. #pragma segment Window
  1523. void    DoContentClick(WindowPtr window, EventRecord *event, Boolean firstClick)
  1524. {
  1525.     FileRecHndl            frHndl;
  1526.     ContentClickProcPtr    proc;
  1527.  
  1528.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1529.  
  1530.     if (!IsDAWindow(window)) {
  1531.         frHndl = (FileRecHndl)GetWRefCon(window);
  1532.         if (frHndl) {
  1533.             proc = (*frHndl)->fileState.contentClickProc;
  1534.             if (proc)
  1535.                 (*proc)(window, event, firstClick);
  1536.         }
  1537.     }
  1538. }
  1539.  
  1540.  
  1541.  
  1542. /*****************************************************************************/
  1543.  
  1544.  
  1545.  
  1546. #pragma segment Window
  1547. void    DoDragWindow(WindowPtr window, EventRecord *event, Rect bounds)
  1548. {
  1549.     WindowPtr    oldPort, fwindow;
  1550.     GrafPort    bigPort;
  1551.     WindowPeek    wpeek;
  1552.     FileRecHndl    frHndl;
  1553.     RgnHandle    dragRgn;
  1554.     Point        offset, windOrg;
  1555.     long        wkind;
  1556.  
  1557.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1558.  
  1559.     if (!StillDown()) return;
  1560.  
  1561.     GetPort(&oldPort);
  1562.  
  1563.     OpenPort(&bigPort);
  1564.     CopyRgn(GetGrayRgn(), bigPort.visRgn);
  1565.     bigPort.portRect = (*bigPort.visRgn)->rgnBBox;
  1566.  
  1567.     if (gSystemVersion >= 0x0700) {
  1568.         HMGetBalloonWindow(&fwindow);
  1569.         if (fwindow)
  1570.             DiffRgn(bigPort.visRgn, ((WindowPeek)fwindow)->strucRgn, bigPort.visRgn);
  1571.     }
  1572.  
  1573.     fwindow = (WindowPtr)-1;
  1574.     wkind = kwIsDocument;
  1575.     frHndl = (FileRecHndl)GetWRefCon(window);
  1576.     if (frHndl)
  1577.         if (((WindowPeek)window)->windowKind >= 1000)
  1578.             wkind = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  1579.     fwindow = FrontWindowOfType(wkind, true);
  1580.     for (wpeek = (WindowPeek)FrontWindow(); wpeek; wpeek = wpeek->nextWindow) {
  1581.         if (fwindow == (WindowPtr)wpeek) break;
  1582.         DiffRgn(bigPort.visRgn, wpeek->strucRgn, bigPort.visRgn);
  1583.     }
  1584.  
  1585.     CopyRgn(((WindowPeek)window)->strucRgn, dragRgn = NewRgn());
  1586.     *(long *)&offset = DragGrayRgn(dragRgn, event->where, &bounds, &bounds, noConstraint, nil);
  1587.  
  1588.     DisposeRgn(dragRgn);
  1589.     ClosePort(&bigPort);
  1590.  
  1591.     if ((offset.h != (short)0x8000) || (offset.v != (short)0x8000)) {
  1592.         windOrg.h = window->portRect.left;
  1593.         windOrg.v = window->portRect.top;
  1594.         SetPort(window);
  1595.         LocalToGlobal(&windOrg);
  1596.         MoveWindow(window, windOrg.h + offset.h, windOrg.v + offset.v, false);
  1597.     }
  1598.  
  1599.     SetPort(oldPort);
  1600.  
  1601.     if (!(event->modifiers & cmdKey))
  1602.         CleanSendInFront(window, fwindow);
  1603. }
  1604.  
  1605.  
  1606.  
  1607. /*****************************************************************************/
  1608.  
  1609.  
  1610.  
  1611. #pragma segment Window
  1612. void    DoDrawFrame(WindowPtr window, Boolean activate)
  1613. {
  1614.     FileRecHndl            frHndl;
  1615.     WindowPtr            oldPort;
  1616.     Rect                worg;
  1617.     long                attributes;
  1618.     DrawFrameProcPtr    proc;
  1619.  
  1620.     if (window) {
  1621.         frHndl = (FileRecHndl)GetWRefCon(window);
  1622.         if (frHndl) {
  1623.             oldPort = SetFilePort(frHndl);
  1624.             worg    = window->portRect;
  1625.             SetOrigin(0, 0);
  1626.     
  1627.             attributes = (*frHndl)->fileState.attributes;
  1628.             if (attributes & kwGrowIcon)
  1629.                 DoDrawGrowIcon(window, false, false);
  1630.  
  1631.             SetOrigin(0, -16384);
  1632.             DoDrawControls(window, true);
  1633.             SetOrigin(-16384, 0);
  1634.             proc = (*frHndl)->fileState.drawFrameProc;
  1635.             if (proc)
  1636.                 (*proc)(frHndl, window, activate);
  1637.     
  1638.             SetOrigin(worg.left, worg.top);
  1639.             SetPort(oldPort);
  1640.         }
  1641.     }
  1642. }
  1643.  
  1644.  
  1645.  
  1646. /*****************************************************************************/
  1647.  
  1648.  
  1649.  
  1650. #pragma segment Window
  1651. OSErr    DoFreeDocument(FileRecHndl frHndl)
  1652. {
  1653.     FreeDocumentProcPtr    proc;
  1654.     OSErr                err;
  1655.  
  1656.     err = noErr;
  1657.     proc = (*frHndl)->fileState.freeDocumentProc;
  1658.     if (proc)
  1659.         err = (*proc)(frHndl);
  1660.     return(err);
  1661. }
  1662.  
  1663.  
  1664.  
  1665. /*****************************************************************************/
  1666.  
  1667.  
  1668.  
  1669. #pragma segment Window
  1670. OSErr    DoFreeWindow(FileRecHndl frHndl, WindowPtr window)
  1671. {
  1672.     FreeWindowProcPtr    proc;
  1673.     OSErr                err;
  1674.  
  1675.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1676.  
  1677.     err = noErr;
  1678.     proc = (*frHndl)->fileState.freeWindowProc;
  1679.     if (proc)
  1680.         err = (*proc)(frHndl, window);
  1681.     return(err);
  1682. }
  1683.  
  1684.  
  1685.  
  1686. /*****************************************************************************/
  1687.  
  1688.  
  1689.  
  1690. #pragma segment Window
  1691. OSErr    DoImageDocument(FileRecHndl frHndl)
  1692. {
  1693.     ImageProcPtr    proc;
  1694.     OSErr            err;
  1695.  
  1696.     err = noErr;
  1697.     proc = (*frHndl)->fileState.imageProc;
  1698.     if (proc)
  1699.         err = (*proc)(frHndl);
  1700.     return(err);
  1701. }
  1702.  
  1703.  
  1704.  
  1705. /*****************************************************************************/
  1706.  
  1707.  
  1708.  
  1709. #pragma segment Window
  1710. OSErr    DoInitContent(FileRecHndl frHndl, WindowPtr window)
  1711. {
  1712.     InitContentProcPtr    proc;
  1713.     OSErr                err;
  1714.  
  1715.     err = noErr;
  1716.     proc = (*frHndl)->fileState.initContentProc;
  1717.     if (proc)
  1718.         err = (*proc)(frHndl, window);
  1719.     return(err);
  1720. }
  1721.  
  1722.  
  1723.  
  1724. /*****************************************************************************/
  1725.  
  1726.  
  1727.  
  1728. #pragma segment Window
  1729. Boolean    DoKeyDown(EventRecord *event)
  1730. {
  1731.     char                key;
  1732.     WindowPtr            window, fwindow;
  1733.     FileRecHndl            frHndl;
  1734.     ContentKeyProcPtr    proc;
  1735.     Boolean                passThrough;
  1736.     short                menuID, menuItem, menuItem2, charsUsed;
  1737.     long                menuVal, attr, wkind;
  1738.     Str32                str;
  1739.     OSType                sftype;
  1740.     OSErr                err;
  1741.     DoMenuItemProcPtr    mproc, mp;
  1742.  
  1743.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1744.  
  1745.     key = event->message & charCodeMask;
  1746.     if (event->modifiers & cmdKey) {        /* If command key down... */
  1747.         if (event->what == keyDown) {
  1748.             DoAdjustMenus();                /* Prepare menus properly. */
  1749.             menuVal   = MenuKey(key);
  1750.             menuID    = HiWord(menuVal);
  1751.             menuItem  = LoWord(menuVal);
  1752.             menuItem2 = MapMItem(menuID, menuItem);
  1753.             if (menuID) {
  1754.                 mproc = DoMenuItem;
  1755.                 if (IsAppWindow(window = FrontWindow())) {
  1756.                     mp = (*(FileRecHndl)GetWRefCon(window))->fileState.doMenuItemProc;
  1757.                     if (mp)
  1758.                         mproc = mp;
  1759.                 }
  1760.                 if (!(*mproc)(window, menuID, menuItem2)) {
  1761.                     GetIndString(str, menuID, menuItem);
  1762.                     if (str[0]) {
  1763.                         p2dec(str, &charsUsed);
  1764.                         if (str[0] > charsUsed + 2) {
  1765.                             if (str[charsUsed + 2] == '\'') {
  1766.                                 BlockMove(str + charsUsed + 3, (Ptr)&sftype, sizeof(OSType));
  1767.                                 window = GetNextWindow(nil, sftype);
  1768.                                 if (window) {
  1769.                                     frHndl = (FileRecHndl)GetWRefCon(window);
  1770.                                     attr   = (*frHndl)->fileState.attributes;
  1771.                                     if (attr & kwHideOnClose) {
  1772.                                         if (!((WindowPeek)window)->visible)
  1773.                                             ShowHide(window, true);
  1774.                                         wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1775.                                         if (!(fwindow = FrontWindowOfType(wkind, false)))
  1776.                                             fwindow = (WindowPtr)-1;
  1777.                                         CleanSendInFront(window, fwindow);
  1778.                                     }
  1779.                                     else window = nil;
  1780.                                 }
  1781.                                 if (!window) {
  1782.                                     err = NewDocumentWindow(&frHndl, sftype, true);
  1783.                                     if (!err) {
  1784.                                         if (frHndl) {
  1785.                                             window = (*frHndl)->fileState.window;
  1786.                                             attr   = (*frHndl)->fileState.attributes;
  1787.                                             if (!((WindowPeek)window)->visible)
  1788.                                                 ShowHide(window, true);
  1789.                                             wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1790.                                             if (!(fwindow = FrontWindowOfType(wkind, false)))
  1791.                                                 fwindow = (WindowPtr)-1;
  1792.                                             CleanSendInFront(window, fwindow);
  1793.                                         }
  1794.                                     }
  1795.                                     else {
  1796.                                         gDialogErr = err;
  1797.                                         NewDocumentWindow(nil, 'ERR#', false);
  1798.                                     }
  1799.                                 }
  1800.                             }
  1801.                         }
  1802.                     }
  1803.                 }
  1804.                 HiliteMenu(0);        /* Unhighlight what MenuKey hilited. */
  1805.                 DoSetCursor(nil);
  1806.                 return(false);
  1807.             }
  1808.         }
  1809.         else return(false);
  1810.     }
  1811.  
  1812.     for (window = nil; (window = GetNextWindow(window, 0)) != nil;) {
  1813.         if (!((WindowPeek)window)->visible) continue;
  1814.         if (((WindowPeek)window)->windowKind >= 1000) {
  1815.             frHndl = (FileRecHndl)GetWRefCon(window);
  1816.             if (frHndl) {
  1817.                 proc = (*frHndl)->fileState.contentKeyProc;
  1818.                 if (proc) {
  1819.                     passThrough = false;
  1820.                     if ((*proc)(window, event, &passThrough)) return(true);
  1821.                     if (!passThrough) break;
  1822.                 }
  1823.             }
  1824.         }
  1825.     }
  1826.  
  1827.     return(false);
  1828. }
  1829.  
  1830.  
  1831.  
  1832. /*****************************************************************************/
  1833.  
  1834.  
  1835.  
  1836. #pragma segment Window
  1837. void    DoMouseDown(EventRecord *event)
  1838. {
  1839.     WindowPtr            window, fwindow, dlog, ww;
  1840.     FileRecHndl            frHndl;
  1841.     Rect                contentRct, old, growLimits, tearRect;
  1842.     Point                pt;
  1843.     short                part, menuID, menuItem, menuItem2, charsUsed;
  1844.     long                menuVal, size, wkind, attr;
  1845.     Str63                str;
  1846.     OSType                sftype;
  1847.     OSErr                err;
  1848.     DoMenuItemProcPtr    mproc, mp;
  1849.  
  1850.     gCursorPtr = nil;        /* Force recalc of cursor. */
  1851.  
  1852.     part = FindWindow(event->where, &window);
  1853.  
  1854.     frHndl = nil;
  1855.     if (window)
  1856.         if (((WindowPeek)window)->windowKind >= 1000)
  1857.             frHndl = (FileRecHndl)GetWRefCon(window);
  1858.  
  1859.     if (part != inContent)
  1860.         DoSetCursor(&qd.arrow);
  1861.  
  1862.     dlog = FrontWindowOfType(kwIsModalDialog, true);
  1863.     if ((dlog) && (window != dlog)) {
  1864.         if (part != inMenuBar) {
  1865.             SysBeep(1);
  1866.             return;
  1867.         }
  1868.     }
  1869.  
  1870.     switch(part) {
  1871.  
  1872.         case inContent:
  1873.  
  1874.             if (!IsAppWindow(window)) {
  1875.                 if (window != FrontWindow()) {
  1876.                     SelectWindow(window);
  1877.                     HiliteWindows();
  1878.                 }
  1879.                 break;
  1880.             }
  1881.  
  1882.             wkind   = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  1883.             fwindow = FrontWindowOfType(wkind, true);
  1884.                 /* fwindow guaranteed, since worst case we find ourself. */
  1885.  
  1886.             if (window == fwindow) {
  1887.                 DoContentClick(window, event, false);
  1888.                 break;
  1889.             }        /* The window is the frontmost of this type, so handle the click. */
  1890.  
  1891.             CleanSendInFront(window, fwindow);
  1892.  
  1893.             if ((*frHndl)->fileState.attributes & kwDoFirstClick) {
  1894.                 DoUpdate(window);
  1895.                 contentRct = GetWindowContentRect(window);
  1896.                 if (PtInRect(event->where, &contentRct))
  1897.                     DoContentClick(window, event, true);
  1898.             }
  1899.             break;
  1900.  
  1901.         case inDrag:
  1902.             DoDragWindow(window, event, qd.screenBits.bounds);
  1903.             break;        /* Pass screenBits.bounds to get all gDevices. */
  1904.  
  1905.         case inGoAway:
  1906.             if (TrackGoAway(window, event->where))
  1907.                 DisposeOneWindow(window, kClose);
  1908.             break;
  1909.  
  1910.         case inGrow:
  1911.             old = GetWindowContentRect(window);
  1912.             growLimits = (*frHndl)->fileState.windowSizeBounds;
  1913.             ++growLimits.right;
  1914.             ++growLimits.bottom;
  1915.             size = GrowWindow(window, event->where, &growLimits);
  1916.             if (size) {
  1917.                 pt = *(Point *)&size;
  1918.                 SizeWindow(window, pt.h, pt.v, true);
  1919.                 DoResizeWindow(window, old.right - old.left, old.bottom - old.top);
  1920.             }
  1921.             break;
  1922.  
  1923.         case inMenuBar:        /* Process mouse menu command (if any). */
  1924.             DoAdjustMenus();
  1925.             DoSetCursor(&qd.arrow);
  1926.             menuVal  = MenuSelect(event->where);
  1927.             menuID   = HiWord(menuVal);
  1928.             menuItem = LoWord(menuVal);
  1929.             if (menuItem == -1)
  1930.                 menuItem = CountMItems(GetMenuHandle(menuID));
  1931.             menuItem2 = MapMItem(menuID, menuItem);
  1932.             mproc = DoMenuItem;
  1933.             if (IsAppWindow(window = FrontWindow())) {
  1934.                 mp = (*(FileRecHndl)GetWRefCon(window))->fileState.doMenuItemProc;
  1935.                 if (mp)
  1936.                     mproc = mp;
  1937.             }
  1938.             if (!(*mproc)(window, menuID, menuItem2)) {
  1939.                 GetIndString(str, menuID, menuItem);
  1940.                 if (str[0]) {
  1941.                     p2dec(str, &charsUsed);
  1942.                     if (str[0] > charsUsed + 2) {
  1943.                         if (str[charsUsed + 2] == '\'') {
  1944.                             BlockMove(str + charsUsed + 3, (Ptr)&sftype, sizeof(OSType));
  1945.                             window = GetNextWindow(nil, sftype);
  1946.                             if (window) {
  1947.                                 frHndl = (FileRecHndl)GetWRefCon(window);
  1948.                                 attr   = (*frHndl)->fileState.attributes;
  1949.                                 if (attr & kwHideOnClose) {
  1950.                                     if (menuItem2 == -1) {
  1951.                                         GetMenuItemText(GetMenuHandle(menuID), menuItem, str);
  1952.                                         BlockMove(str + 1, &tearRect, sizeof(Rect));
  1953.                                         MoveWindow(window, tearRect.left, tearRect.top, false);
  1954.                                     }
  1955.                                     if (!((WindowPeek)window)->visible)
  1956.                                         ShowHide(window, true);
  1957.                                     wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1958.                                     if (!(fwindow = FrontWindowOfType(wkind, false)))
  1959.                                         fwindow = (WindowPtr)-1;
  1960.                                     CleanSendInFront(window, fwindow);
  1961.                                 }
  1962.                                 else window = nil;
  1963.                             }
  1964.                             if (!window) {
  1965.                                 err = NewDocumentWindow(&frHndl, sftype, true);
  1966.                                 if (!err) {
  1967.                                     if (frHndl) {
  1968.                                         window = (*frHndl)->fileState.window;
  1969.                                         attr   = (*frHndl)->fileState.attributes;
  1970.                                         if (!((WindowPeek)window)->visible)
  1971.                                             ShowHide(window, true);
  1972.                                         wkind = (attr & (kwIsPalette | kwIsModalDialog));
  1973.                                         if (!(fwindow = FrontWindowOfType(wkind, false)))
  1974.                                             fwindow = (WindowPtr)-1;
  1975.                                         CleanSendInFront(window, fwindow);
  1976.                                     }
  1977.                                 }
  1978.                                 else {
  1979.                                     gDialogErr = err;
  1980.                                     NewDocumentWindow(nil, 'ERR#', false);
  1981.                                 }
  1982.                             }
  1983.                         }
  1984.                     }
  1985.                 }
  1986.             }
  1987.             HiliteMenu(0);        /* Unhighlight what MenuSelect hilited. */
  1988.             break;
  1989.  
  1990.         case inSysWindow:    /* Let the system handle the mouseDown. */
  1991.             SystemClick(event, window);
  1992.             for (ww = FrontWindow(); ww; ww = (WindowPtr)(((WindowPeek)ww)->nextWindow))
  1993.                 if (ww == window) break;
  1994.                     /* We have to go find out if the window was closed ourselves.  Silly, huh. */
  1995.             if (!ww) WindowGoneFixup(window);
  1996.             break;
  1997.  
  1998.         case inZoomIn:
  1999.         case inZoomOut:
  2000.             DoZoomWindow(window, event, part);
  2001.             break;
  2002.  
  2003.     }
  2004. }
  2005.  
  2006.  
  2007.  
  2008. /*****************************************************************************/
  2009.  
  2010.  
  2011.  
  2012. /* This function converts a menu item hard-id (one returned by the toolbox) to a
  2013. ** soft-id (defined in the 'STR#' resource associated with the menu.  If there is
  2014. ** a 'STR#' resource defined with the same id as the menu, it is assumed to be
  2015. ** for the purpose of converting hard-id values to soft-id values. */
  2016.  
  2017. #pragma segment Window
  2018. short    MapMItem(short menuID, short menuItem)
  2019. {
  2020.     Str32    str;
  2021.  
  2022.     if (menuID == 128)
  2023.         return(menuItem);
  2024.  
  2025.     GetIndString(str, menuID, menuItem);
  2026.     if (str[0])
  2027.         menuItem = p2dec(str, nil);
  2028.  
  2029.     return(menuItem);
  2030. }
  2031.  
  2032.  
  2033.  
  2034. /*****************************************************************************/
  2035.  
  2036.  
  2037.  
  2038. /* This function is the logical reverse of MapMItem(). */
  2039.  
  2040. #pragma segment Window
  2041. short    UnmapMItem(short menuID, short menuItem)
  2042. {
  2043.     Str32    str;
  2044.     short    i, j;
  2045.  
  2046.     if (menuID == 128)                   return(menuItem);
  2047.     if (!Get1Resource('STR#', menuID)) return(menuItem);
  2048.         /* No such table, so don't convert it. */
  2049.  
  2050.     if (menuItem) {
  2051.         for (i = 1;; ++i) {
  2052.             GetIndString(str, menuID, i);
  2053.             if (!str[0]) return(32767);        /* No such entry found.  Return something invalid. */
  2054.             j = p2dec(str, nil);
  2055.             if (menuItem == j) return(i);
  2056.         }
  2057.     }
  2058. }
  2059.  
  2060.  
  2061.  
  2062. /*****************************************************************************/
  2063.  
  2064.  
  2065.  
  2066. #pragma segment Window
  2067. OSErr    DoReadDocument(FileRecHndl frHndl)
  2068. {
  2069.     ReadDocumentProcPtr    proc;
  2070.     OSErr                err;
  2071.  
  2072.     err = noErr;
  2073.     proc = (*frHndl)->fileState.readDocumentProc;
  2074.     if (proc)
  2075.         err = (*proc)(frHndl);
  2076.     return(err);
  2077. }
  2078.  
  2079.  
  2080.  
  2081. /*****************************************************************************/
  2082.  
  2083.  
  2084.  
  2085. #pragma segment Window
  2086. OSErr    DoReadDocumentHeader(FileRecHndl frHndl)
  2087. {
  2088.     ReadDocumentHeaderProcPtr    proc;
  2089.     OSErr                        err;
  2090.  
  2091.     err = noErr;
  2092.     if ((*frHndl)->fileState.refNum) {
  2093.         proc = (*frHndl)->fileState.readDocumentHeaderProc;
  2094.         if (proc)
  2095.             err = (*proc)(frHndl);
  2096.     }
  2097.     return(err);
  2098. }
  2099.  
  2100.  
  2101.  
  2102. /*****************************************************************************/
  2103.  
  2104.  
  2105.  
  2106. #pragma segment Window
  2107. OSErr    DefaultReadDocumentHeader(FileRecHndl frHndl)
  2108. {
  2109.     short    refNum, vers, resAlreadyOpen, oldRes;
  2110.     OSErr    err;
  2111.     char    hstate;
  2112.     Ptr        ptr1, ptr2;
  2113.     long    count, attr;
  2114.     OSType    sftype;
  2115.     Handle    hndl;
  2116.  
  2117.     err = SetFPos(refNum = (*frHndl)->fileState.refNum, fsFromStart, 0);
  2118.     if (err) return(err);
  2119.  
  2120.     attr   = (*frHndl)->fileState.attributes;
  2121.     sftype = (*frHndl)->fileState.sfType;
  2122.  
  2123.     if (attr & kwDefaultDocHeader) {
  2124.         if (sftype != MovieFileType) {
  2125.             if (attr & kwHeaderIsResource) {
  2126.                 resAlreadyOpen = (*frHndl)->fileState.resRefNum;
  2127.                 UseDocResFile(frHndl, &oldRes, fsRdWrPerm);
  2128.                 hndl = Get1Resource('DFDH', 128);
  2129.                 err  = ResError();
  2130.                 if (!err)
  2131.                     if (!hndl)
  2132.                         err = resNotFound;
  2133.                 if (!err) {
  2134.                     ptr1   = (Ptr)&((*frHndl)->d.doc);
  2135.                     ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2136.                     count  = (long)ptr2 - (long)ptr1;
  2137.                     BlockMove(*hndl, ptr1, count);
  2138.                 }
  2139.                 if (hndl)
  2140.                     ReleaseResource(hndl);
  2141.                 if (!resAlreadyOpen)
  2142.                     CloseDocResFile(frHndl);
  2143.                 UseResFile(oldRes);
  2144.             }
  2145.             else {
  2146.                 if (!err) {        /* Read header info from file. */
  2147.                     hstate = HGetState((Handle)frHndl);
  2148.                     HLock((Handle)frHndl);
  2149.                     ptr1   = (Ptr)&((*frHndl)->d.doc);
  2150.                     ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2151.                     count  = (long)ptr2 - (long)ptr1;
  2152.                     err    = FSRead(refNum, &count, ptr1);
  2153.                     HSetState((Handle)frHndl, hstate);
  2154.                 }
  2155.             }
  2156.             if (!err) {
  2157.                 vers = (*frHndl)->d.doc.fhInfo.version;
  2158.                 if ((vers < gMinVersion) || (vers > gMaxVersion))
  2159.                     err = kWrongVersion;
  2160.             }
  2161.         }
  2162.     }
  2163.  
  2164.     return(err);
  2165. }
  2166.  
  2167.  
  2168.  
  2169. /*****************************************************************************/
  2170.  
  2171.  
  2172.  
  2173. #pragma segment Window
  2174. OSErr    DoWriteDocument(FileRecHndl frHndl)
  2175. {
  2176.     WriteDocumentProcPtr    proc;
  2177.     OSErr                    err;
  2178.  
  2179.     err = noErr;
  2180.     proc = (*frHndl)->fileState.writeDocumentProc;
  2181.     if (proc)
  2182.         err = (*proc)(frHndl);
  2183.     return(err);
  2184. }
  2185.  
  2186.  
  2187.  
  2188. /*****************************************************************************/
  2189.  
  2190.  
  2191.  
  2192. #pragma segment Window
  2193. OSErr    DoWriteDocumentHeader(FileRecHndl frHndl)
  2194. {
  2195.     WriteDocumentHeaderProcPtr    proc;
  2196.     OSErr                        err;
  2197.  
  2198.     err = noErr;
  2199.     if ((*frHndl)->fileState.refNum) {
  2200.         proc = (*frHndl)->fileState.writeDocumentHeaderProc;
  2201.         if (proc)
  2202.             err = (*proc)(frHndl);
  2203.     }
  2204.     return(err);
  2205. }
  2206.  
  2207.  
  2208.  
  2209. /*****************************************************************************/
  2210.  
  2211.  
  2212.  
  2213. #pragma segment Window
  2214. OSErr    DefaultWriteDocumentHeader(FileRecHndl frHndl)
  2215. {
  2216.     short        refNum, resAlreadyOpen, oldRes;
  2217.     OSErr        err;
  2218.     WindowPtr    window;
  2219.     char        hstate;
  2220.     Ptr            ptr1, ptr2;
  2221.     long        count, attr;
  2222.     OSType        sftype;
  2223.     Handle        hndl;
  2224.  
  2225.     err = SetFPos(refNum = (*frHndl)->fileState.refNum, fsFromStart, 0);
  2226.     if (err) return(err);
  2227.  
  2228.     attr   = (*frHndl)->fileState.attributes;
  2229.     sftype = (*frHndl)->fileState.sfType;
  2230.  
  2231.     if (attr & kwDefaultDocHeader) {
  2232.         if (sftype != MovieFileType) {
  2233.             window = (*frHndl)->fileState.window;
  2234.             if (window) {
  2235.                 if (!(*frHndl)->fileState.readOnly) {
  2236.                     (*frHndl)->d.doc.fhInfo.structureRect = GetWindowStructureRect(window);
  2237.                     (*frHndl)->d.doc.fhInfo.contentRect   = GetWindowContentRect(window);
  2238.                     (*frHndl)->d.doc.fhInfo.stdState      = mDerefWStateData(window)->stdState;
  2239.                     if (((WindowPeek)window)->spareFlag)
  2240.                         (*frHndl)->d.doc.fhInfo.userState = mDerefWStateData(window)->userState;
  2241.                 }
  2242.             }
  2243.             else SetRect(&(*frHndl)->d.doc.fhInfo.structureRect, 0, 0, 0, 0);
  2244.             if (attr & kwHeaderIsResource) {
  2245.                 resAlreadyOpen = (*frHndl)->fileState.resRefNum;
  2246.                 UseDocResFile(frHndl, &oldRes, fsRdWrPerm);
  2247.                 ptr1   = (Ptr)&((*frHndl)->d.doc);
  2248.                 ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2249.                 count  = (long)ptr2 - (long)ptr1;
  2250.                 hndl = Get1Resource('DFDH', 128);
  2251.                 if (hndl) {
  2252.                     RemoveResource(hndl);
  2253.                     DisposeHandle(hndl);
  2254.                 }
  2255.                 hndl = NewHandle(count);
  2256.                 if (hndl) {
  2257.                     ptr1 = (Ptr)&((*frHndl)->d.doc);
  2258.                     BlockMove(ptr1, *hndl, count);
  2259.                     AddResource(hndl, 'DFDH', 128, nil);
  2260.                     ChangedResource(hndl);
  2261.                     WriteResource(hndl);
  2262.                     UpdateResFile(CurResFile());
  2263.                     DetachResource(hndl);
  2264.                     DisposeHandle(hndl);
  2265.                 }
  2266.                 else err = memFullErr;
  2267.                 if (!resAlreadyOpen)
  2268.                     CloseDocResFile(frHndl);
  2269.                 UseResFile(oldRes);
  2270.             }
  2271.             else {
  2272.                 hstate = HGetState((Handle)frHndl);
  2273.                 HLock((Handle)frHndl);
  2274.                 ptr1   = (Ptr)&((*frHndl)->d.doc);
  2275.                 ptr2   = (Ptr)&((*frHndl)->d.doc.fhInfo.endDocHeaderInfo);
  2276.                 count  = (long)ptr2 - (long)ptr1;
  2277.                 err    = FSWrite(refNum, &count, ptr1);
  2278.                 HSetState((Handle)frHndl, hstate);
  2279.             }
  2280.         }
  2281.     }
  2282.  
  2283.     return(err);
  2284. }
  2285.  
  2286.  
  2287.  
  2288. /*****************************************************************************/
  2289.  
  2290.  
  2291.  
  2292. #pragma segment Window
  2293. void    DoResizeContent(WindowPtr window, short oldh, short oldv)
  2294. {
  2295.     FileRecHndl                frHndl;
  2296.     ResizeContentProcPtr    proc;
  2297.  
  2298.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2299.  
  2300.     if (IsAppWindow(window)) {
  2301.         frHndl = (FileRecHndl)GetWRefCon(window);
  2302.         if (frHndl) {
  2303.             proc = (*frHndl)->fileState.resizeContentProc;
  2304.             if (proc)
  2305.                 (*proc)(window, oldh, oldv);
  2306.         }
  2307.     }
  2308. }
  2309.  
  2310.  
  2311.  
  2312. /*****************************************************************************/
  2313.  
  2314.  
  2315.  
  2316. #pragma segment Window
  2317. void    DoScrollFrame(WindowPtr window, long dh, long dv)
  2318. {
  2319.     FileRecHndl            frHndl;
  2320.     ScrollFrameProcPtr    proc;
  2321.  
  2322.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2323.  
  2324.     if (IsAppWindow(window)) {
  2325.         frHndl = (FileRecHndl)GetWRefCon(window);
  2326.         if (frHndl) {
  2327.             proc = (*frHndl)->fileState.scrollFrameProc;
  2328.             if (proc)
  2329.                 (*proc)(frHndl, window, dh, dv);
  2330.         }
  2331.     }
  2332. }
  2333.  
  2334.  
  2335.  
  2336. /*****************************************************************************/
  2337.  
  2338.  
  2339.  
  2340. #pragma segment Window
  2341. void    DoUndoFixup(FileRecHndl frHndl, Point contOrg, Boolean afterUndo)
  2342. {
  2343.     UndoFixupProcPtr    proc;
  2344.  
  2345.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2346.  
  2347.     proc = (*frHndl)->fileState.undoFixupProc;
  2348.     if (proc)
  2349.         (*proc)(frHndl, contOrg, afterUndo);
  2350. }
  2351.  
  2352.  
  2353.  
  2354. /*****************************************************************************/
  2355. /*****************************************************************************/
  2356.  
  2357.  
  2358.  
  2359. /* Open a window where it was stored at.  This would be simple, except for the
  2360. ** complication that the user may be opening the document on a different Mac
  2361. ** that doesn't have the same monitor configuration.  Due to this, we need to
  2362. ** make sure that the window doesn't open completely out of view. */
  2363.  
  2364. #pragma segment Window
  2365. static Rect    OldLocWindow(WindowPtr window, WindowPtr relatedWindow, Rect sizeInfo)
  2366. {
  2367.     FileRecHndl    frHndl;
  2368.     RgnHandle    rgn;
  2369.     Rect        rct, bbox, srct, crct;
  2370.     short        dh, dv, h, v;
  2371.     long        attributes;
  2372.  
  2373.     frHndl     = (FileRecHndl)GetWRefCon(window);
  2374.     attributes = (*frHndl)->fileState.attributes;
  2375.  
  2376.     srct = (*frHndl)->d.doc.fhInfo.structureRect;
  2377.     crct = (*frHndl)->d.doc.fhInfo.contentRect;
  2378.     if (EmptyRect(&srct)) {
  2379.         if (!gOldLocProc) return(window->portRect);
  2380.         return((*gOldLocProc)(window, relatedWindow, sizeInfo));
  2381.     }
  2382.  
  2383.     rct = srct;
  2384.     rct.bottom = crct.top;
  2385.  
  2386.     RectRgn(rgn = NewRgn(), &rct);
  2387.     SectRgn(rgn, GetGrayRgn(), rgn);
  2388.     bbox = (*rgn)->rgnBBox;
  2389.     DisposeRgn(rgn);
  2390.  
  2391.     if (EqualRect(&rct, &bbox)) {
  2392.         rct = (*frHndl)->d.doc.fhInfo.contentRect;
  2393.         SizeWindow(window, rct.right - rct.left, rct.bottom - rct.top, false);
  2394.         MoveWindow(window, rct.left, rct.top, false);
  2395.         mDerefWStateData(window)->stdState  = (*frHndl)->d.doc.fhInfo.stdState;
  2396.         if (((WindowPeek)window)->spareFlag)
  2397.             mDerefWStateData(window)->userState = (*frHndl)->d.doc.fhInfo.userState;
  2398.         return(rct);
  2399.     }
  2400.  
  2401.     rct = srct;
  2402.     if (!(dh = bbox.left - rct.left))
  2403.         dh = bbox.right  - rct.right;
  2404.     if (!(dv = bbox.top  - rct.top))
  2405.         dv = bbox.bottom - rct.bottom;
  2406.     OffsetRect(&rct, dh, dv);
  2407.  
  2408.     RectRgn(rgn = NewRgn(), &rct);
  2409.     SectRgn(rgn, GetGrayRgn(), rgn);
  2410.     bbox = (*rgn)->rgnBBox;
  2411.     DisposeRgn(rgn);
  2412.  
  2413.     if (EqualRect(&rct, &bbox)) {
  2414.         h = crct.right  - crct.left;
  2415.         v = crct.bottom - crct.top;
  2416.         SetRect(&sizeInfo, h, v, h, v);
  2417.             /* Force window big as possible for this screen and data size. */
  2418.     }
  2419.  
  2420.     if (!gOldLocProc) return(window->portRect);
  2421.     return((*gOldLocProc)(window, relatedWindow, sizeInfo));
  2422. }
  2423.  
  2424.  
  2425.  
  2426. /*****************************************************************************/
  2427.  
  2428.  
  2429.  
  2430. #pragma segment Window
  2431. void    CleanSendBehind(WindowPtr window, WindowPtr afterWindow)
  2432. {
  2433.     WindowPtr    oldPort;
  2434.     Point        offset;
  2435.     RgnHandle    contRgn, keepContRgn, visRgn;
  2436.  
  2437.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2438.  
  2439.     if (afterWindow == (WindowPtr)-1) {
  2440.         BringToFront(window);
  2441.         HiliteWindows();
  2442.         return;
  2443.     }
  2444.  
  2445.     GetPort(&oldPort);
  2446.     SetPort(window);
  2447.     offset.h = offset.v = 0;
  2448.     LocalToGlobal(&offset);
  2449.     SetPort(oldPort);
  2450.  
  2451.     CopyRgn(contRgn = ((WindowPeek)window)->contRgn, keepContRgn = NewRgn());
  2452.     OffsetRgn(visRgn = window->visRgn, offset.h, offset.v);
  2453.     DiffRgn(contRgn, visRgn, contRgn);
  2454.     OffsetRgn(visRgn, -offset.h, -offset.v);
  2455.         /* Don't allow PaintOne to touch the part of the window already visible. */
  2456.  
  2457.     SendBehind(window, afterWindow);
  2458.         /* Do the SendBehind.  Since the content region is way off the
  2459.         ** screen(s), no erasing of the content of the window will occur. */
  2460.  
  2461.     CopyRgn(keepContRgn, contRgn);
  2462.     DisposeRgn(keepContRgn);
  2463.  
  2464.     CalcVis((WindowPeek)window);
  2465.         /* One negative to the content region games is that the visRgn gets
  2466.         ** calculated incorrectly when SendBehind() is called.  The call to
  2467.         ** CalcVis() fixes this problem. */
  2468.  
  2469.     HiliteWindows();
  2470. }
  2471.  
  2472.  
  2473.  
  2474. /*****************************************************************************/
  2475.  
  2476.  
  2477.  
  2478. #pragma segment Window
  2479. void    CleanSendInFront(WindowPtr window, WindowPtr beforeWindow)
  2480. {
  2481.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2482.  
  2483.     beforeWindow = GetPreviousWindow(beforeWindow);
  2484.     if (beforeWindow)
  2485.         CleanSendBehind(window, beforeWindow);
  2486. }
  2487.  
  2488.  
  2489.  
  2490. /*****************************************************************************/
  2491.  
  2492.  
  2493.  
  2494. #pragma segment Window
  2495. void    HiliteWindows(void)
  2496. {
  2497.     WindowPtr    window, ww;
  2498.     FileRecHndl    frHndl, ff;
  2499.     long        thisKind, lastKind;
  2500.     Boolean        haveModal;
  2501.  
  2502.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2503.  
  2504.     lastKind = -1;            /* No such kind. */
  2505.  
  2506.     haveModal = false;
  2507.     for (window = FrontWindow(); window; window = (WindowPtr)(((WindowPeek)window)->nextWindow)) {
  2508.  
  2509.         if (!((WindowPeek)window)->visible)          continue;
  2510.         if (((WindowPeek)window)->windowKind < 1000) continue;
  2511.  
  2512.         thisKind = kwIsDocument;
  2513.         if (IsAppWindow(window)) {
  2514.             frHndl   = (FileRecHndl)GetWRefCon(window);
  2515.             thisKind = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  2516.         }
  2517.  
  2518.         if (gInBackground)
  2519.             lastKind = thisKind;
  2520.                 /* If application moved to background, we want to turn all hilighting off
  2521.                 ** for all windows.  This is accomplished by pretending that the kind of
  2522.                 ** the current window is the same as the kind of the last window. */
  2523.  
  2524.         if (haveModal)
  2525.             lastKind = thisKind;
  2526.                 /* If we have a modal dialog in front, then turn off the hilighting for
  2527.                 ** all the other windows. */
  2528.  
  2529.         if (thisKind != lastKind) {
  2530.             for (ww = window; (ww = (WindowPtr)(((WindowPeek)ww)->nextWindow)) != nil;) {
  2531.                 if (!((WindowPeek)ww)->visible) continue;
  2532.                 if ((IsAppWindow(ww)) || (IsDAWindow(window))) {
  2533.                     ff = (FileRecHndl)GetWRefCon(ww);
  2534.                     if (thisKind == ((*ff)->fileState.attributes & (kwIsPalette | kwIsModalDialog))) {
  2535.                         if (thisKind == kwIsPalette) {
  2536.                             if (!((WindowPeek)ww)->hilited) {
  2537.                                 HiliteWindow(ww, true);
  2538.                                 DoActivate(ww);
  2539.                             }
  2540.                         }
  2541.                         else {
  2542.                             if (((WindowPeek)ww)->hilited) {
  2543.                                 HiliteWindow(ww, false);
  2544.                                 DoActivate(ww);
  2545.                             }
  2546.                         }
  2547.                     }
  2548.                     else break;
  2549.                 }
  2550.             }
  2551.             if (!((WindowPeek)window)->hilited) {
  2552.                 HiliteWindow(window, true);
  2553.                 DoActivate(window);
  2554.             }
  2555.             lastKind = thisKind;
  2556.         }
  2557.         else {
  2558.             if (((WindowPeek)window)->hilited) {
  2559.                 HiliteWindow(window, false);
  2560.                 DoActivate(window);
  2561.             }
  2562.         }
  2563.  
  2564.         if (thisKind == kwIsModalDialog)
  2565.             haveModal = true;
  2566.     }
  2567. }
  2568.  
  2569.  
  2570.  
  2571. /*****************************************************************************/
  2572.  
  2573.  
  2574.  
  2575. #pragma segment Window
  2576. void    UnhiliteWindows(void)
  2577. {
  2578.     WindowPtr    window;
  2579.  
  2580.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2581.  
  2582.     for (window = nil; (window = GetNextWindow(window, 0)) != nil;) {
  2583.         if (!((WindowPeek)window)->visible) continue;
  2584.         if (IsAppWindow(window))
  2585.             if (((WindowPeek)window)->windowKind <= dialogKind)
  2586.                 continue;
  2587.         if (((WindowPeek)window)->hilited) {
  2588.             HiliteWindow(window, false);
  2589.             DoActivate(window);
  2590.         }
  2591.     }
  2592. }
  2593.  
  2594.  
  2595.  
  2596. /*****************************************************************************/
  2597.  
  2598.  
  2599.  
  2600. /* This is called when an update event is received for a window.  First, the
  2601. ** updateRgn is separated into two parts.  Part 1 holds the window frame area,
  2602. ** if any.  This is the area that might hold the scrollbars, grow icon, and
  2603. ** any other application-specific frame parts.  This is drawn first.  Once
  2604. ** this is done, the remainder of the updateRgn is drawn.  This allows us to
  2605. ** handle all of the frame clipping without using the clipRgn.  By freeing up
  2606. ** the clipRgn, we allow the application to use it without having to share. */
  2607.  
  2608. #pragma segment Window
  2609. void    DoUpdate(WindowPtr window)
  2610. {
  2611.     RgnHandle    contPart, framePart;
  2612.     Point        contOrg;
  2613.     FileRecHndl    frHndl;
  2614.  
  2615.     SetPort(window);
  2616.  
  2617.     if (IsAppWindow(window)) {
  2618.  
  2619.         DoUpdateSeparate(window, &contPart, &framePart);
  2620.  
  2621.         if (framePart) {        /* Update the document frame, if any. */
  2622.             CopyRgn(framePart, ((WindowPeek)window)->updateRgn);
  2623.             DisposeRgn(framePart);
  2624.             ++gBeginUpdateNested;
  2625.             BeginUpdate(window);
  2626.             DoDrawFrame(window, false);
  2627.             if (gBeginUpdateNested) {
  2628.                 EndUpdate(window);
  2629.                 --gBeginUpdateNested;
  2630.             }
  2631.         }
  2632.         if (contPart) {            /* Update the rest of the content. */
  2633.             CopyRgn(contPart, ((WindowPeek)window)->updateRgn);
  2634.             DisposeRgn(contPart);
  2635.             ++gBeginUpdateNested;
  2636.             BeginUpdate(window);
  2637.             GetContentOrigin(window, &contOrg);
  2638.             SetOrigin(contOrg.h, contOrg.v);
  2639.             frHndl = (FileRecHndl)GetWRefCon(window);
  2640.             DoImageDocument(frHndl);
  2641.             SetOrigin(0, 0);
  2642.             if (gBeginUpdateNested) {
  2643.                 EndUpdate(window);
  2644.                 --gBeginUpdateNested;
  2645.             }
  2646.         }
  2647.     }
  2648. }
  2649.  
  2650.  
  2651.  
  2652. /*****************************************************************************/
  2653.  
  2654.  
  2655.  
  2656. #pragma segment Window
  2657. void    DoSetCursor(Cursor *cursor)
  2658. {
  2659.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2660.  
  2661.     if (cursor)
  2662.         SetCursor(cursor);
  2663.  
  2664.     if (!cursor)
  2665.         DoCursor();
  2666. }
  2667.  
  2668.  
  2669.  
  2670. /*****************************************************************************/
  2671.  
  2672.  
  2673.  
  2674. #pragma segment Window
  2675. CursPtr    DoSetResCursor(short crsrID)
  2676. {
  2677.     CursHandle    crsr;
  2678.  
  2679.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2680.  
  2681.     crsr = GetCursor(crsrID);
  2682.     if (crsr) {
  2683.         gCursor = **crsr;
  2684.         DoSetCursor(&gCursor);
  2685.         return(&gCursor);
  2686.     }
  2687.  
  2688.     SetCursor(&qd.arrow);
  2689.     return(&qd.arrow);
  2690. }
  2691.  
  2692.  
  2693.  
  2694. /*****************************************************************************/
  2695.  
  2696.  
  2697.  
  2698. #pragma segment Window
  2699. void    DoWindowCursor(void)
  2700. {
  2701.     WindowPeek            wpeek;
  2702.     WindowPtr            window;
  2703.     Point                mouseLoc;
  2704.     FileRecHndl            frHndl;
  2705.     RgnHandle            srgn;
  2706.     WindowCursorProcPtr    proc;
  2707.  
  2708.     if (gInBackground) return;
  2709.         /* Don't change cursors if we aren't the front application. */
  2710.  
  2711.     if (!gCursorRgn)
  2712.         gCursorRgn = NewRgn();
  2713.  
  2714.     mouseLoc = GetGlobalMouse();
  2715.  
  2716.     if (!(wpeek = (WindowPeek)FrontWindow())) {
  2717.         SetRectRgn(gCursorRgn, -30000, -30000, 30000, 30000);
  2718.         WindowCursor(nil, nil, mouseLoc);
  2719.         return;
  2720.     }
  2721.  
  2722.     if (!IsAppWindow((WindowPtr)wpeek)) {
  2723.         SetRectRgn(gCursorRgn, -30000, -30000, 30000, 30000);
  2724.         SetCursor(gCursorPtr = &qd.arrow);
  2725.     }        /* Non-application windows get an arrow cursor. */
  2726.  
  2727.     if (gCursorPtr) {                            /* Do we already have a cursor... */
  2728.         if (PtInRgn(mouseLoc, gCursorRgn)) {    /* Are we still in the cursor area... */
  2729.             SetCursor(gCursorPtr);                /* Then set it to that. */
  2730.             return;
  2731.         }
  2732.     }
  2733.  
  2734.     SetRectRgn(gCursorRgn, -30000, -30000, 30000, 30000);
  2735.  
  2736.     for (wpeek = (WindowPeek)FrontWindow();; wpeek = wpeek->nextWindow) {
  2737.  
  2738.         if (!IsAppWindow((WindowPtr)wpeek)) break;
  2739.  
  2740.         if (!wpeek->visible) continue;        /* No cursors for invisible windows. */
  2741.  
  2742.         window = (WindowPtr)wpeek;
  2743.         srgn   = wpeek->strucRgn;
  2744.         frHndl = (FileRecHndl)GetWRefCon(window);
  2745.  
  2746.         proc = (frHndl) ? (*frHndl)->fileState.windowCursorProc : nil;
  2747.         if (!proc) {
  2748.             if (PtInRgn(mouseLoc, srgn)) {
  2749.                 SectRgn(gCursorRgn, srgn, gCursorRgn);
  2750.                 SetCursor(gCursorPtr = &qd.arrow);
  2751.                 return;
  2752.             }
  2753.         }
  2754.         else if ((*proc)(frHndl, window, mouseLoc)) return;
  2755.  
  2756.         DiffRgn(gCursorRgn, srgn, gCursorRgn);
  2757.     }
  2758.  
  2759.     SetCursor(gCursorPtr = &qd.arrow);
  2760. }
  2761.  
  2762.  
  2763.  
  2764. /*****************************************************************************/
  2765.  
  2766.  
  2767.  
  2768. #pragma segment Window
  2769. WindowPtr    FrontWindowOfType(long wkind, Boolean firstVis)
  2770. {
  2771.     WindowPtr    window;
  2772.     FileRecHndl    frHndl;
  2773.     long        wk;
  2774.  
  2775.     wkind &= (kwIsPalette | kwIsModalDialog);
  2776.     for (window = nil; (window = GetNextWindow(window, 0)) != nil;) {
  2777.         if (firstVis)
  2778.             if (!(((WindowPeek)window)->visible))
  2779.                 continue;
  2780.         if (IsDAWindow(window))
  2781.             if (wkind == kwIsDocument)
  2782.                 return(window);
  2783.         if (((WindowPeek)window)->windowKind >= 1000) {
  2784.             frHndl = (FileRecHndl)GetWRefCon(window);
  2785.             if (frHndl) {
  2786.                 wk = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  2787.                 if (wk < wkind)  break;
  2788.                 if (wk == wkind) return(window);
  2789.             }
  2790.         }
  2791.     }
  2792.  
  2793.     return(nil);
  2794. }
  2795.  
  2796.  
  2797.  
  2798. /*****************************************************************************/
  2799.  
  2800.  
  2801.  
  2802. /* This function gets an alert, and handles hiliting of windows correctly.
  2803. ** The reason for this function is that there may be more than one hilited
  2804. ** window due to the possibility of floating palettes.  The calls to UnhiliteWindows
  2805. ** and HiliteWindows make sure that while the alert is up, there are no other
  2806. ** hilited windows. */
  2807.  
  2808. #pragma segment Window
  2809. short    HCenteredAlert(short alertID, WindowPtr relatedWindow, ModalFilterUPP filter)
  2810. {
  2811.     short    itemHit;
  2812.  
  2813.     gCursorPtr = nil;        /* Force recalc of cursor. */
  2814.  
  2815.     UnhiliteWindows();
  2816.     itemHit = CenteredAlert(alertID, relatedWindow, filter);
  2817.     HiliteWindows();
  2818.     return(itemHit);
  2819. }
  2820.  
  2821.  
  2822.  
  2823. /*****************************************************************************/
  2824. /*****************************************************************************/
  2825.  
  2826.  
  2827.  
  2828. /* This function gets the application window formats that were created with
  2829. ** the AppsToGo application editor.  The window formats are stored in the resource
  2830. ** 'WFMT' id #128.  They are first read in, and then they are unflattened
  2831. ** by calling HReadWindowFormats(). */
  2832.  
  2833. #pragma segment Window
  2834. OSErr    GetWindowFormats(void)
  2835. {
  2836.     Handle    wfmt;
  2837.     OSErr    err;
  2838.  
  2839.     if (!(wfmt = GetAppResource('WFMT', 128, nil))) return(ResError());
  2840.     DetachResource(wfmt);
  2841.  
  2842.     err = HReadWindowFormats(wfmt);
  2843.     DisposeHandle(wfmt);
  2844.  
  2845.     return(err);
  2846. }
  2847.  
  2848.  
  2849.  
  2850. /*****************************************************************************/
  2851.  
  2852.  
  2853.  
  2854. /* This function is called to unflatten a window-format handle into separate
  2855. ** hierarchical document objects.  The assumption is that there is only one
  2856. ** of these multiple window definitions, and therefore if there is already
  2857. ** one in the global gWindowFormats, it is disposed of.  This is exactly the
  2858. ** behavior needed by the AppsToGo application editor. */
  2859.  
  2860. #pragma segment Window
  2861. OSErr    HReadWindowFormats(Handle wfmt)
  2862. {
  2863.     TreeObjHndl        wobj;
  2864.     long            attr;
  2865.     short            i, j;
  2866.     OSErr            err;
  2867.     static OSType    *lastTypeListPtr;
  2868.  
  2869.     err = noErr;
  2870.     NewDocument(nil, 0, 0);        /* This resets the doc.increment value. */
  2871.  
  2872.     if (wfmt) {
  2873.         if (gWindowFormats)
  2874.             DisposeObjAndOffspring(gWindowFormats);
  2875.         if (!(gWindowFormats = NewRootObj(WFMTOBJ, 0))) return(memFullErr);
  2876.         err = HReadTree(gWindowFormats, wfmt);
  2877.     }
  2878.  
  2879.     if (!err) {
  2880.         gTypeListLen       = 0;
  2881.         gAppWindowAttr     = 0;
  2882.         gAppWindowType     = 0;
  2883.         gNoDefaultDocument = true;
  2884.         for (i = 0; i < (*gWindowFormats)->numChildren; ++i) {
  2885.             wobj = GetChildHndl(gWindowFormats, i);
  2886.             attr = mDerefWFMT(wobj)->attributes;
  2887.             if (!(attr & kwRuntimeOnlyDoc))
  2888.                 ++gTypeListLen;
  2889.             if (attr & kwDefaultDocType) {
  2890.                 gAppWindowAttr     = attr;
  2891.                 gAppWindowType     = mDerefWFMT(wobj)->sfType;
  2892.                 gNoDefaultDocument = false;
  2893.             }
  2894.         }
  2895.         if (gTypeListLen) {
  2896.             if (lastTypeListPtr)
  2897.                 DisposePtr((Ptr)lastTypeListPtr);
  2898.             gTypeListPtr = lastTypeListPtr = (OSType *)NewPtr(gTypeListLen * sizeof(OSType));
  2899.             if (!gTypeListPtr)
  2900.                 return(memFullErr);
  2901.             for (i = j = 0; i < (*gWindowFormats)->numChildren; ++i) {
  2902.                 wobj = GetChildHndl(gWindowFormats, i);
  2903.                 attr = mDerefWFMT(wobj)->attributes;
  2904.                 if (!(attr & kwRuntimeOnlyDoc))
  2905.                     gTypeListPtr[j++] = mDerefWFMT(wobj)->sfType;
  2906.             }
  2907.         }
  2908.     }
  2909.  
  2910.     return(err);
  2911. }
  2912.  
  2913.  
  2914.  
  2915. /*****************************************************************************/
  2916.  
  2917.  
  2918.  
  2919. /* This function is called to add a named 'WFMT' resource that isn't included in
  2920. ** the 'WFMT' id #128 standard resource.  The purpose for not including all of
  2921. ** the 'WFMT' resources into the id #128 is for speed reasons.  For really complex
  2922. ** applications, the number of items in the various windows and dialogs can cause
  2923. ** a huge number of handled to be created, thus slowing down the application.
  2924. ** By separating out one or more window definitions and saving them off, the size
  2925. ** of the main 'WFMT' resource can be reduced.  Named 'WFMT' resources should be
  2926. ** named with the document type used to reference them.  They are read in, used,
  2927. ** and then disposed of automatically. */
  2928.  
  2929. #pragma segment Window
  2930. OSErr    GetSeparateWFMT(OSType sftype, short *numAdded)
  2931. {
  2932.     short            i, nadd, *naddptr;
  2933.     TreeObjHndl        wfmt;
  2934.     OSErr            err;
  2935.     Handle            hndl;
  2936.     Str15            str;
  2937.  
  2938.     nadd    = 0;
  2939.     naddptr = (numAdded) ? numAdded : &nadd;
  2940.  
  2941.     if (!sftype) {
  2942.         while (*naddptr)
  2943.             DisposeChild(NO_EDIT, gWindowFormats, --*naddptr);
  2944.         return(noErr);
  2945.     }
  2946.  
  2947.     *naddptr = 0;
  2948.     for (i = (*gWindowFormats)->numChildren; i;) {
  2949.         wfmt = GetChildHndl(gWindowFormats, --i);
  2950.         if (mDerefWFMT(wfmt)->sfType == sftype) return(noErr);
  2951.     }
  2952.  
  2953.     str[0] = 4;
  2954.     BlockMove(&sftype, str + 1, sizeof(OSType));
  2955.     hndl = GetAppNamedResource('WFMT', str, &err);
  2956.     if (err) return(err);
  2957.  
  2958.     if (hndl) {
  2959.         DetachResource(hndl);
  2960.         wfmt = NewChild(NO_EDIT, gWindowFormats, *naddptr, WFMTOBJ, 0);
  2961.         if (!wfmt) {
  2962.             DisposeHandle(hndl);
  2963.             DisposeChild(NO_EDIT, gWindowFormats, *naddptr);
  2964.             return(memFullErr);
  2965.         }
  2966.  
  2967.         err = HReadTree(wfmt, hndl);        /* Unflatten the WFMT resource into the place-holder */
  2968.         DisposeHandle(hndl);
  2969.  
  2970.         if (err) {
  2971.             DisposeChild(NO_EDIT, gWindowFormats, *naddptr);
  2972.             return(err);
  2973.         }
  2974.  
  2975.         for (; (*wfmt)->numChildren;)
  2976.             MoveChild(NO_EDIT, wfmt, 0, gWindowFormats, (*naddptr)++);
  2977.  
  2978.         DisposeChild(NO_EDIT, gWindowFormats, *naddptr);
  2979.     }
  2980.  
  2981.     return(noErr);
  2982. }
  2983.  
  2984.  
  2985.  
  2986. /*****************************************************************************/
  2987. /*****************************************************************************/
  2988.  
  2989.  
  2990.  
  2991. /* This function adds a set of controls (and sets referenced by that set) to the
  2992. ** window.  The control sets are created with the AppsToGo application editor. */
  2993.  
  2994. #pragma segment Window
  2995. OSErr    AddControlSet(WindowPtr window, OSType sftype, short visMode,
  2996.                       short xoffset, short yoffset, CObjCtlHndl retcoc)
  2997. {
  2998.     WindowPtr            oldPort;
  2999.     ControlHandle        ctl, dataCtl;
  3000.     CObjCtlHndl            coc;
  3001.     short                cocnum, i, j, len, ii, jj, vm, xo, yo, numAdded;
  3002.     OSType                sft;
  3003.     long                ofst, oldSize, newSize;
  3004.     TreeObjHndl            wfmt, cobj;
  3005.     char                str[256];
  3006.     OSErr                err;
  3007.     Rect                rct;
  3008.  
  3009.     if (!gWindowFormats) return(noErr);
  3010.  
  3011.     SetRect(&rct, 0, 0, 0, 0);
  3012.     dataCtl = NewControl(window, &rct, "\p", false, 0,0,0, gDataCtl + 7, sftype);
  3013.     if (!dataCtl) return(memFullErr);
  3014.  
  3015.     if (!(coc = (CObjCtlHndl)NewHandle(0x100))) return(memFullErr);
  3016.  
  3017.     err = GetSeparateWFMT(sftype, &numAdded);
  3018.     if (err) return(err);
  3019.  
  3020.     GetPort(&oldPort);
  3021.     SetPort(window);
  3022.  
  3023.     (*dataCtl)->contrlData = (Handle)coc;
  3024.     cocnum = 0;
  3025.  
  3026.     for (i = (*gWindowFormats)->numChildren; i;) {
  3027.         wfmt = GetChildHndl(gWindowFormats, --i);
  3028.         if (mDerefWFMT(wfmt)->sfType == sftype) {
  3029.             for (j = 0; j < (*wfmt)->numChildren; ++j) {
  3030.                 cobj = GetChildHndl(wfmt, j);
  3031.                 ctl  = MakeControl(window, cobj, visMode, xoffset, yoffset);
  3032.                 if (ctl) {
  3033.                     SetHandleSize((Handle)coc, (((++cocnum * sizeof(CObjCtl)) | 0xFF) + 1));
  3034.                     (**coc)[--cocnum].ctlObj  = cobj;    /* The handle was already big enough. */
  3035.                     (**coc)[cocnum  ].ctl     = ctl;
  3036.                     (**coc)[cocnum  ].visible = mDerefCtl(cobj)->visible;
  3037.                     (**coc)[cocnum++].procID  = mDerefCtl(cobj)->procID;
  3038.                     err = MemError();
  3039.                 }
  3040.                 if (!ctl) err = memFullErr;
  3041.                 if (err) {
  3042.                     SetHandleSize((Handle)coc, cocnum * sizeof(CObjCtl));
  3043.                     SetPort(oldPort);
  3044.                     GetSeparateWFMT(0, &numAdded);
  3045.                     return(err);
  3046.                 }
  3047.             }
  3048.  
  3049.             ofst = GetDataOffset(wfmt, offsetof(WFMTObj,title), kPStr, 1);
  3050.             GetPData(wfmt, ofst, (StringPtr)str);
  3051.             len = str[0];
  3052.             p2c((StringPtr)str);
  3053.             for (ii = 0; ii < len;) {
  3054.                 BlockMove(str + ii + 1, &sft, sizeof(OSType));
  3055.                 ii += sizeof(OSType) + 3;
  3056.                 vm = c2dec(str + ii, &jj);
  3057.                 ii += ++jj;
  3058.                 xo = c2dec(str + ii, &jj);
  3059.                 ii += ++jj;
  3060.                 yo = c2dec(str + ii, &jj);
  3061.                 ii += ++jj;
  3062.                 mDerefWFMT(wfmt)->sfType = 0;
  3063.                     /* Prevent self-references, which cause infinite recursion (boom). */
  3064.                 err = AddControlSet(window, sft, vm, xoffset + xo, yoffset + yo, retcoc);
  3065.                 mDerefWFMT(wfmt)->sfType = sftype;
  3066.                 if (err) {
  3067.                     SetHandleSize((Handle)coc, cocnum * sizeof(CObjCtl));
  3068.                     SetPort(oldPort);
  3069.                     GetSeparateWFMT(0, &numAdded);
  3070.                     return(err);
  3071.                 }
  3072.             }
  3073.         }
  3074.     }
  3075.  
  3076.     newSize = cocnum * sizeof(CObjCtl);
  3077.     SetHandleSize((Handle)coc, newSize);
  3078.  
  3079.     SetPort(oldPort);
  3080.  
  3081.     GetSeparateWFMT(0, &numAdded);
  3082.  
  3083.     if (retcoc) {
  3084.         oldSize = GetHandleSize((Handle)retcoc);
  3085.         SetHandleSize((Handle)retcoc, oldSize + newSize);
  3086.         err = MemError();
  3087.         if (err) return(err);
  3088.         BlockMove(*coc, (*(Handle)retcoc) + oldSize, newSize);
  3089.     }
  3090.  
  3091.     return(noErr);
  3092. }
  3093.  
  3094.  
  3095.  
  3096. /*****************************************************************************/
  3097.  
  3098.  
  3099.  
  3100. #pragma segment Window
  3101.  
  3102. static pascal void    DefaultScrollAction(ControlHandle ctl, short part);
  3103. static pascal void    DefaultScrollAction(ControlHandle ctl, short part)
  3104. {
  3105.     short                delta, value;
  3106.     short                oldValue, min, max;
  3107.     ControlStyleInfo    cinfo;
  3108.     Boolean                vert;
  3109.     short                hArrowVal = 1;
  3110.     short                vArrowVal = 1;
  3111.     short                hPageVal = 10;
  3112.     short                vPageVal = 10;
  3113.  
  3114.     cinfo.scrollProc = nil;
  3115.     if (GetControlStyle(ctl, &cinfo)) {
  3116.         if (cinfo.hArrowVal) hArrowVal = cinfo.hArrowVal;
  3117.         if (cinfo.vArrowVal) vArrowVal = cinfo.vArrowVal;
  3118.         if (cinfo.hPageVal)  hPageVal  = cinfo.hPageVal;
  3119.         if (cinfo.vPageVal)  vPageVal  = cinfo.vPageVal;
  3120.     }
  3121.  
  3122.     vert = (((*ctl)->contrlRect.right - (*ctl)->contrlRect.left) == 16);
  3123.  
  3124.     if (part) {                        /* If it was actually in the control. */
  3125.  
  3126.         switch (part) {
  3127.             case inUpButton:
  3128.             case inDownButton:        /* One line. */
  3129.                 delta = (vert) ? vArrowVal : hArrowVal;
  3130.                 break;
  3131.             case inPageUp:            /* One page. */
  3132.             case inPageDown:
  3133.                 delta = (vert) ? vPageVal : hPageVal;
  3134.                 break;
  3135.         }
  3136.  
  3137.         if ( (part == inUpButton) || (part == inPageUp) )
  3138.             delta = -delta;        /* Reverse direction for an upper. */
  3139.  
  3140.         value = (oldValue = GetControlValue(ctl)) + delta;
  3141.         if (value < (min = GetControlMinimum(ctl))) value = min;
  3142.         if (value > (max = GetControlMaximum(ctl))) value = max;
  3143.  
  3144.         if (value != oldValue)
  3145.             SetControlValue(ctl, value);
  3146.  
  3147.         if (cinfo.scrollProc) (*cinfo.scrollProc)(ctl, part, oldValue, value);
  3148.     }
  3149. }
  3150.  
  3151. static Boolean    DefaultScroll(ControlHandle ctl, short part, EventRecord *event);
  3152. static Boolean    DefaultScroll(ControlHandle ctl, short part, EventRecord *event)
  3153. {
  3154.     short                oldValue, newValue;
  3155.     ControlStyleInfo    cinfo;
  3156.  
  3157.     static ControlActionUPP    cupp;
  3158.  
  3159.     oldValue = newValue = GetControlValue(ctl);
  3160.     switch (part) {
  3161.         case inThumb:
  3162.             if (TrackControl(ctl, event->where, nil)) {
  3163.                 newValue = GetControlValue(ctl);
  3164.                 if (oldValue != newValue) {
  3165.                     if (GetControlStyle(ctl, &cinfo))
  3166.                         if (cinfo.scrollProc)
  3167.                             (*cinfo.scrollProc)(ctl, part, oldValue, newValue);
  3168.                 }
  3169.             }
  3170.             break;
  3171.         default:
  3172.             if (!cupp) cupp = NewControlActionProc(DefaultScrollAction);
  3173.             TrackControl(ctl, event->where, cupp);
  3174.             newValue = GetControlValue(ctl);
  3175.             break;
  3176.     }
  3177.  
  3178.     return((oldValue != newValue) ? true : false);
  3179. }
  3180.  
  3181. static void    AddRect(Rect *r1, Rect *r2, Rect *r3);
  3182. static void    AddRect(Rect *r1, Rect *r2, Rect *r3)
  3183. {
  3184.     Rect    r;
  3185.  
  3186.     r = *r1;    
  3187.     r.top    += r2->top;
  3188.     r.left   += r2->left;
  3189.     r.bottom += r2->bottom;
  3190.     r.right  += r2->right;
  3191.     if ((r.left >= r.right) || (r.top >= r.bottom)) SetRect(&r, 0, 0, 0, 0);
  3192.     *r3 = r;
  3193. }
  3194.  
  3195. /* This function is used to create a control based on the control definition object.
  3196. ** The control definition objects are created with the AppsToGo application editor. */
  3197.  
  3198. #pragma segment Window
  3199. ControlHandle    MakeControl(WindowPtr window, TreeObjHndl cobj, short visMode, short xoffset, short yoffset)
  3200. {
  3201.     WindowPtr            oldPort;
  3202.     ControlHandle        ctl;
  3203.     short                cctbID, tlen, slen, vis, maxTextLen;
  3204.     short                variant, rr, cc, ll, procID, mode;
  3205.     long                ofst;
  3206.     ControlStyleInfo    cinfo;
  3207.     CCTabHandle            cctbHndl;
  3208.     TEHandle            te;
  3209.     ListHandle            list;
  3210.     Handle                txt;
  3211.     StScrpHandle        styl;
  3212.     Ptr                    ptr;
  3213.     Point                cell;
  3214.     Rect                destRct, viewRct, brdrRct;
  3215.     char                hstate;
  3216.     CtlTemplate            **crsrc;
  3217.     short                txFont, txSize, fnum;
  3218.     Style                txFace;
  3219.  
  3220.     GetPort(&oldPort);
  3221.     SetPort(window);
  3222.  
  3223.     HLock((Handle)cobj);
  3224.     OffsetRect(&mDerefCtl(cobj)->rect, xoffset, yoffset);
  3225.  
  3226.     variant = (mDerefCtl(cobj)->procID & 0x0F);
  3227.     ctl = nil;
  3228.     vis  = mDerefCtl(cobj)->visible;
  3229.     vis |= visMode;
  3230.     vis ^= (visMode > 1);
  3231.     vis &= 0x01;
  3232.  
  3233.     cinfo.ctlID       = mDerefCtl(cobj)->ctlID;
  3234.     cinfo.trackProc   = nil;
  3235.     cinfo.scrollProc  = nil;
  3236.     cinfo.hArrowVal   = 0;
  3237.     cinfo.vArrowVal   = 0;
  3238.     cinfo.hPageVal    = 0;
  3239.     cinfo.vPageVal    = 0;
  3240.     cinfo.drawControl = nil;
  3241.     cinfo.fontSize    = mDerefCtl(cobj)->fontSize;
  3242.     cinfo.fontStyle   = mDerefCtl(cobj)->fontStyle;
  3243.     ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 1);
  3244.     GetPData(cobj, ofst, cinfo.keyEquivs);
  3245.     ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 2);
  3246.     GetPData(cobj, ofst, cinfo.font);
  3247.     ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 3);
  3248.     GetPData(cobj, ofst, cinfo.balloonHelp);
  3249.     txFont = window->txFont;
  3250.     txSize = window->txSize;
  3251.     txFace = window->txFace;
  3252.     procID = mDerefCtl(cobj)->procID;
  3253.     if (procID & 0x08) {
  3254.         TextFace(cinfo.fontStyle);
  3255.         fnum = 0;
  3256.         if (cinfo.font[0])
  3257.             GetFNum(cinfo.font, &fnum);
  3258.         TextFont(fnum);
  3259.         TextSize(cinfo.fontSize);
  3260.     }
  3261.  
  3262.     switch (procID & 0xFFF0) {
  3263.         case rTECtl:
  3264.             destRct = mDerefCtl(cobj)->extCtl.ctenew.destRct;
  3265.             viewRct = mDerefCtl(cobj)->extCtl.ctenew.viewRct;
  3266.             brdrRct = mDerefCtl(cobj)->extCtl.ctenew.brdrRct;
  3267.             maxTextLen = mDerefCtl(cobj)->extCtl.ctenew.maxTextLen;
  3268.             if (maxTextLen < 1) {
  3269.                 maxTextLen = -maxTextLen;
  3270.                 AddRect(&mDerefCtl(cobj)->rect, &destRct, &destRct);
  3271.                 AddRect(&mDerefCtl(cobj)->rect, &viewRct, &viewRct);
  3272.                 AddRect(&mDerefCtl(cobj)->rect, &brdrRct, &brdrRct);
  3273.             }
  3274.             else {
  3275.                 OffsetRect(&destRct, xoffset, yoffset);
  3276.                 OffsetRect(&viewRct, xoffset, yoffset);
  3277.                 OffsetRect(&brdrRct, xoffset, yoffset);
  3278.             }
  3279.             CTENew(gTECtl + variant,
  3280.                    false, window, &te,
  3281.                   &mDerefCtl(cobj)->rect,
  3282.                   &destRct, &viewRct, &brdrRct,
  3283.                    maxTextLen, mDerefCtl(cobj)->extCtl.ctenew.mode
  3284.             );
  3285.             if (te) {
  3286.                 UseControlStyle(ctl = CTEViewFromTE(te));
  3287.                 ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 4);
  3288.                 BlockMove((char *)GetDataPtr(cobj) + ofst, &tlen, sizeof(short));
  3289.                 txt = NewHandle(tlen);
  3290.                 if (txt) {
  3291.                     ptr = GetDataPtr(cobj);
  3292.                     BlockMove(ptr + ofst + sizeof(short), *txt, tlen);
  3293.                     slen = 0;
  3294.                     styl = nil;
  3295.                     if (mDerefCtl(cobj)->extCtl.ctenew.mode & cteStyledTE) {
  3296.                         ofst = GetDataOffset(cobj, ofst, kSDataBlock, 1);
  3297.                         BlockMove((char *)GetDataPtr(cobj) + ofst, &slen, sizeof(short));
  3298.                         if (slen)
  3299.                             styl = (StScrpHandle)NewHandle(slen);
  3300.                         if (styl) {
  3301.                             ptr = GetDataPtr(cobj);
  3302.                             BlockMove(ptr + ofst + sizeof(short), (Ptr)*styl, slen);
  3303.                         }
  3304.                     }
  3305.                     DisposeHandle(CTESwapText(te, txt, styl, false));
  3306.                     if (styl)
  3307.                         DisposeHandle((Handle)styl);
  3308.                     if (!(*ctl)->contrlHilite)
  3309.                          if (mDerefCtl(cobj)->extCtl.ctenew.mode & cteActive)
  3310.                             if (!CTEReadOnly(te))
  3311.                                 CTESetSelect(mDerefCtl(cobj)->min, mDerefCtl(cobj)->max, te);
  3312.                 }
  3313.                 UseControlStyle(nil);
  3314.             }
  3315.             break;
  3316.         case rListCtl:
  3317.             mode = mDerefCtl(cobj)->extCtl.clnew.mode;
  3318.             if (!gclvVariableSizeCells)
  3319.                 mode &= (0xFFFF - clVariable);
  3320.             list = CLNew(gListCtl + variant,
  3321.                          false,
  3322.                         &mDerefCtl(cobj)->rect,
  3323.                          mDerefCtl(cobj)->extCtl.clnew.numRows,
  3324.                          mDerefCtl(cobj)->extCtl.clnew.numCols,
  3325.                          mDerefCtl(cobj)->extCtl.clnew.cellHeight,
  3326.                          mDerefCtl(cobj)->extCtl.clnew.cellWidth,
  3327.                          mDerefCtl(cobj)->refCon,
  3328.                          window,
  3329.                          (mode & (0xFFFF - clVariable))
  3330.             );
  3331.             if (list) {
  3332.                 (*list)->listFlags |= 0x08;
  3333.                 ctl  = CLViewFromList(list);
  3334.                 ofst = GetDataOffset(cobj, offsetof(CtlObj,title), kPStr, 4);
  3335.                 BlockMove((char *)GetDataPtr(cobj) + ofst, &tlen, sizeof(short));
  3336.                 txt = NewHandle(tlen);
  3337.                 if (txt) {
  3338.                     ptr = GetDataPtr(cobj);
  3339.                     BlockMove(ptr + ofst + sizeof(short), *txt, tlen);
  3340.                     ofst = 0;
  3341.                     HLock(txt);
  3342.                     for (rr = 0; rr < mDerefCtl(cobj)->extCtl.clnew.numRows; ++rr) {
  3343.                         if (ofst >= tlen) break;
  3344.                         for (cc = 0; cc < mDerefCtl(cobj)->extCtl.clnew.numCols; ++cc) {
  3345.                             if (ofst >= tlen) break;
  3346.                             cell.h = cc;
  3347.                             cell.v = rr;
  3348.                             ll = ((unsigned char *)*txt)[ofst];
  3349.                             LSetCell(*txt + ofst + 1, ll, cell, list);
  3350.                             ofst += ++ll;
  3351.                         }
  3352.                     }
  3353.                     DisposeHandle(txt);
  3354.                 }
  3355.                 if (mode & clVariable)
  3356.                     (*gclvVariableSizeCells)(list);
  3357.                 else
  3358.                     if ((mDerefCtl(cobj)->extCtl.clnew.mode) & clDrawIt)
  3359.                         (*list)->listFlags &= (0xFFFF - 0x08);
  3360.             }
  3361.             break;
  3362.         case rCIconCtl:
  3363.             ctl = CCIconNew(window,
  3364.                            &mDerefCtl(cobj)->rect,
  3365.                  (StringPtr)mDerefCtl(cobj)->title,
  3366.                             false,
  3367.                             mDerefCtl(cobj)->value,
  3368.                             mDerefCtl(cobj)->min,
  3369.                             mDerefCtl(cobj)->max,
  3370.                             gCIconCtl + variant,
  3371.                             mDerefCtl(cobj)->refCon
  3372.             );
  3373.             break;
  3374.         case rPICTCtl:
  3375.             ctl = CPICTNew(window,
  3376.                           &mDerefCtl(cobj)->rect,
  3377.                 (StringPtr)mDerefCtl(cobj)->title,
  3378.                            false,
  3379.                            mDerefCtl(cobj)->value,
  3380.                            mDerefCtl(cobj)->min,
  3381.                            mDerefCtl(cobj)->max,
  3382.                            gPICTCtl + variant,
  3383.                            mDerefCtl(cobj)->refCon
  3384.             );
  3385.             break;
  3386.         default:
  3387.             procID = mDerefCtl(cobj)->procID;
  3388.             if (procID == -1) {
  3389.                 crsrc = (CtlTemplate **)GetResource('CNTL', mDerefCtl(cobj)->refCon);
  3390.                 if (crsrc) {
  3391.                     hstate = HGetState((Handle)crsrc);
  3392.                     HLock((Handle)crsrc);
  3393.                     ctl = NewControl(window,
  3394.                               &mDerefCtl(cobj)->rect,
  3395.                     (StringPtr)(*crsrc)->contrlTitle,
  3396.                                false,
  3397.                                (*crsrc)->contrlValue,
  3398.                                (*crsrc)->contrlMin,
  3399.                                (*crsrc)->contrlMax,
  3400.                                (*crsrc)->procID,
  3401.                                (*crsrc)->contrlRfCon
  3402.                     );
  3403.                     HSetState((Handle)crsrc, hstate);
  3404.                     if (((*crsrc)->procID & 0xFFF0) == popupMenuProc)
  3405.                         gPopupProc = (*ctl)->contrlDefProc;
  3406.                 }
  3407.                 if (ctl) break;
  3408.                 procID = 0;
  3409.             }
  3410.             if ((procID > rPICTCtl) && (procID < rDataCtl + 16))
  3411.                     procID += (gDataCtl - rDataCtl);
  3412.                         /* For AppsToGo to be able to use the target's CDEF's,
  3413.                         ** we have to have unique numbers for the extended controls.
  3414.                         ** AppsToGo has added a constant to all of the extended
  3415.                         ** controls for this reason.  We have to do the same for
  3416.                         ** these extra extended controls so that the contrlDefProc
  3417.                         ** is constant for compare purposes. */
  3418.             ctl = NewControl(window,
  3419.                       &mDerefCtl(cobj)->rect,
  3420.             (StringPtr)mDerefCtl(cobj)->title,
  3421.                        false,
  3422.                        mDerefCtl(cobj)->value,
  3423.                        mDerefCtl(cobj)->min,
  3424.                        mDerefCtl(cobj)->max,
  3425.                        procID,
  3426.                        mDerefCtl(cobj)->refCon
  3427.             );
  3428.             if (procID == scrollBarProc) cinfo.trackProc = DefaultScroll;
  3429.             break;
  3430.     }
  3431.  
  3432.     TextFont(txFont);
  3433.     TextSize(txSize);
  3434.     TextFace(txFace);
  3435.  
  3436.     OffsetRect(&mDerefCtl(cobj)->rect, -xoffset, -yoffset);
  3437.     HUnlock((Handle)cobj);
  3438.  
  3439.     if (ctl) {
  3440.         HiliteControl(ctl, mDerefCtl(cobj)->hilite);
  3441.         SetControlStyle(ctl, &cinfo);
  3442.         cctbID = mDerefCtl(cobj)->cctbID;
  3443.         if (cctbID) {
  3444.             if (gQDVersion > kQDOriginal) {
  3445.                 cctbHndl = (CCTabHandle)GetResource('cctb', cctbID);
  3446.                 if (cctbHndl)
  3447.                     SetControlColor(ctl, cctbHndl);
  3448.             }
  3449.         }
  3450.  
  3451.         if (vis) {
  3452.             switch (mDerefCtl(cobj)->procID & 0xFFF0) {
  3453.                 case rTECtl:
  3454.                     CTEShow((TEHandle)GetControlReference(ctl));
  3455.                     break;
  3456.                 case rListCtl:
  3457.                     CLShow((ListHandle)GetControlReference(ctl));
  3458.                     break;
  3459.                 default:
  3460.                     ShowControl(ctl);
  3461.                     break;
  3462.             }
  3463.         }
  3464.     }
  3465.  
  3466.     SetPort(oldPort);
  3467.     return(ctl);
  3468. }
  3469.  
  3470.  
  3471.  
  3472. /*****************************************************************************/
  3473.  
  3474.  
  3475.  
  3476. /* This function is called to return the handle of the Data control that has
  3477. ** a reference to all of the controls in the control set.  Once you get the
  3478. ** Data control, you can then look at the data in the control to get the handle
  3479. ** of the controls within the control set. */
  3480.  
  3481. #pragma segment Window
  3482. CObjCtlHndl    GetControlSet(WindowPtr window, OSType sftype, ControlHandle *retDataCtl)
  3483. {
  3484.     ControlHandle    dataCtl;
  3485.     CObjCtlHndl        coc;
  3486.  
  3487.     for (dataCtl = nil; (dataCtl = CDataNext(window, dataCtl)) != nil;) {
  3488.         if ((*dataCtl)->contrlRfCon != sftype) continue;
  3489.         if (GetControlVariant(dataCtl) != 7)   continue;
  3490.         coc = (CObjCtlHndl)(*dataCtl)->contrlData;
  3491.         if (coc) {
  3492.             if (retDataCtl) *retDataCtl = dataCtl;
  3493.             return(coc);
  3494.         }
  3495.     }
  3496.  
  3497.     if (retDataCtl) *retDataCtl = nil;
  3498.     return(nil);
  3499. }
  3500.  
  3501.  
  3502.  
  3503. /*****************************************************************************/
  3504.  
  3505.  
  3506.  
  3507. /* This function is used to show or hide a set of controls. */
  3508.  
  3509. #pragma segment Window
  3510. void    DisplayControlSet(WindowPtr window, OSType sftype, short visMode)
  3511. {
  3512.     WindowPtr        curPort;
  3513.     CObjCtlHndl        coc;
  3514.     short            i, vis;
  3515.     ControlHandle    ctl;
  3516.     Rect            rct;
  3517.  
  3518.     GetPort(&curPort);
  3519.     SetPort(window);
  3520.     coc = GetControlSet(window, sftype, nil);
  3521.     if (coc) {
  3522.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3523.             ctl = (**coc)[--i].ctl;
  3524.             vis = (**coc)[  i].visible;
  3525.             vis = ((vis | visMode) ^ (visMode > 1)) & 0x01;
  3526.             if (vis) {
  3527.                 switch ((**coc)[i].procID & 0xFFF0) {
  3528.                     case rTECtl:
  3529.                         CTEShow((TEHandle)GetControlReference(ctl));
  3530.                         break;
  3531.                     case rListCtl:
  3532.                         CLShow((ListHandle)GetControlReference(ctl));
  3533.                         break;
  3534.                     default:
  3535.                         ShowStyledControl(ctl);
  3536.                         break;
  3537.                 }
  3538.             }
  3539.             else {
  3540.                 switch ((**coc)[i].procID & 0xFFF0) {
  3541.                     case rTECtl:
  3542.                         rct = CTEHide((TEHandle)GetControlReference(ctl));
  3543.                         if (!(visMode & kwInvalOnHide)) ValidRect(&rct);
  3544.                         break;
  3545.                     case rListCtl:
  3546.                         rct = CLHide((ListHandle)GetControlReference(ctl));
  3547.                         if (!(visMode & kwInvalOnHide)) ValidRect(&rct);
  3548.                         break;
  3549.                     default:
  3550.                         HideStyledControl(ctl);
  3551.                         if (!(visMode & kwInvalOnHide)) {
  3552.                             rct = (*ctl)->contrlRect;
  3553.                             if (GetButtonVariant(ctl) == pushButProc)
  3554.                                 if ((*ctl)->contrlValue)
  3555.                                     InsetRect(&rct, kButtonFrameInset, kButtonFrameInset);
  3556.                             ValidRect(&rct);
  3557.                         }
  3558.                         break;
  3559.                 }
  3560.             }
  3561.         }
  3562.     }
  3563.     SetPort(curPort);
  3564. }
  3565.  
  3566.  
  3567.  
  3568. /*****************************************************************************/
  3569.  
  3570.  
  3571.  
  3572. /* This function is used to draw a set of controls. */
  3573.  
  3574. #pragma segment Window
  3575. void    DrawControlSet(WindowPtr window, OSType sftype)
  3576. {
  3577.     CObjCtlHndl        coc;
  3578.     short            i, j;
  3579.     ControlHandle    ctl, cc;
  3580.     ListHandle        list;
  3581.  
  3582.     coc = GetControlSet(window, sftype, nil);
  3583.     if (coc) {
  3584.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3585.             ctl = (**coc)[--i].ctl;
  3586.             DoDraw1Control(ctl, false);
  3587.             switch ((**coc)[i].procID & 0xFFF0) {
  3588.                 case rTECtl:
  3589.                     for (j = 0; j < 2; ++j) {
  3590.                         cc = CTEScrollFromView(ctl, j);
  3591.                         if (cc) DoDraw1Control(cc, false);
  3592.                     }
  3593.                     break;
  3594.                 case rListCtl:
  3595.                     list = (ListHandle)GetControlReference(ctl);
  3596.                     if (list) {
  3597.                         if ((*list)->vScroll) DoDraw1Control((*list)->vScroll, false);
  3598.                         if ((*list)->hScroll) DoDraw1Control((*list)->hScroll, false);
  3599.                     }
  3600.                     break;
  3601.             }
  3602.         }
  3603.     }
  3604. }
  3605.  
  3606.  
  3607.  
  3608. /*****************************************************************************/
  3609.  
  3610.  
  3611.  
  3612. /* This function is used to dispose a set of controls. */
  3613.  
  3614. #pragma segment Window
  3615. void    DisposeControlSet(WindowPtr window, OSType sftype)
  3616. {
  3617.     CObjCtlHndl        coc;
  3618.     ControlHandle    dataCtl;
  3619.     short            i;
  3620.  
  3621.     coc = GetControlSet(window, sftype, &dataCtl);
  3622.     if (coc) {
  3623.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3624.             HideStyledControl((**coc)[--i].ctl);
  3625.             DisposeControl((**coc)[i].ctl);
  3626.         }
  3627.         DisposeControl(dataCtl);
  3628.     }
  3629. }
  3630.  
  3631.  
  3632.  
  3633. /*****************************************************************************/
  3634.  
  3635.  
  3636.  
  3637. /* This function is used to dispose a set of controls. */
  3638.  
  3639. #pragma segment Window
  3640. void    DisposeControlFromSet(ControlHandle ctl, OSType sftype)
  3641. {
  3642.     WindowPtr        window;
  3643.     CObjCtlHndl        coc;
  3644.     ControlHandle    dataCtl;
  3645.     short            i, s, o;
  3646.     Ptr                p;
  3647.  
  3648.     window = (*ctl)->contrlOwner;
  3649.     coc = GetControlSet(window, sftype, &dataCtl);
  3650.     if (coc) {
  3651.         for (i = GetHandleSize((Handle)coc) / sizeof(CObjCtl); i;) {
  3652.             if (ctl == (**coc)[--i].ctl) {
  3653.                 DisposeControl(ctl);
  3654.                 s = GetHandleSize((Handle)coc);
  3655.                 o = i * sizeof(CObjCtl);
  3656.                 p = (Ptr)*coc;
  3657.                 BlockMove(p + o + sizeof(CObjCtl), p + o, s - o - sizeof(CObjCtl));
  3658.                 SetHandleSize((Handle)coc, s - sizeof(CObjCtl));
  3659.                 if (s == sizeof(CObjCtl)) DisposeControl(dataCtl);
  3660.                 return;
  3661.             }
  3662.         }
  3663.     }
  3664. }
  3665.  
  3666.  
  3667.  
  3668. /*****************************************************************************/
  3669.  
  3670.  
  3671.  
  3672. /* This fuction is called to adjust all of the menus in the designated MBAR. 
  3673. ** The functions gets each menu handle, and then disables all of the menu items
  3674. ** for that menu.  It then calls the application to give the application the
  3675. ** chance to enable the appropriate menu items. */
  3676.  
  3677. #pragma segment Window
  3678. Boolean    DoAdjustMBARMenus(WindowPtr window, short menuBarID)
  3679. {
  3680.     FileRecHndl                frHndl;
  3681.     short                    **mbar, i;
  3682.     long                    oldFlags;
  3683.     AdjustMenuItemsProcPtr    proc;
  3684.     Boolean                    redrawMenuBar;
  3685.     MenuHandle                menu;
  3686.  
  3687.     redrawMenuBar = false;
  3688.  
  3689.     proc = AdjustMenuItems;
  3690.     if (window) {
  3691.         if (((WindowPeek)window)->windowKind >= 1000) {
  3692.             frHndl = (FileRecHndl)GetWRefCon(window);
  3693.             if (frHndl)
  3694.                 proc = (*frHndl)->fileState.adjustMenuItemsProc;
  3695.         }
  3696.     }
  3697.  
  3698.     mbar = (short **)GetAppResource('MBAR', menuBarID, nil);
  3699.     if (mbar) {
  3700.         for (i = **mbar; i; --i) {
  3701.             menu = GetMenuHandle((*mbar)[i]);
  3702.             if (menu) {
  3703.                 oldFlags             = (*menu)->enableFlags;
  3704.                 (*menu)->enableFlags = oldFlags & 0x01;
  3705.                 redrawMenuBar       |= (*proc)(window, (*mbar)[i]);
  3706.                 if ((*menu)->enableFlags & 0xFFFFFFFEL) EnableItem(menu, 0);
  3707.                 else                                    DisableItem(menu, 0);
  3708.                 if ((oldFlags & 0x01) != ((*menu)->enableFlags & 0x01))
  3709.                     redrawMenuBar = true;
  3710.             }
  3711.         }
  3712.     }
  3713.  
  3714.     return(redrawMenuBar);
  3715. }
  3716.  
  3717.  
  3718.  
  3719. /*****************************************************************************/
  3720.  
  3721.  
  3722.  
  3723. /* This function is used to open all of the windows that are correctly designated
  3724. ** with the AppsToGo application editor.  You should call this in your application
  3725. ** at startup time if your application is editable with the AppsToGo application editor. */
  3726.  
  3727. #pragma segment Window
  3728. OSErr    OpenRuntimeOnlyAutoNewWindows(void)
  3729. {
  3730.     FileRecHndl    frHndl;
  3731.     OSErr        err;
  3732.     short        i;
  3733.     TreeObjHndl    wobj;
  3734.     long        attr;
  3735.  
  3736.     err = noErr;
  3737.     if (gWindowFormats) {
  3738.         for (i = (*gWindowFormats)->numChildren; i;) {
  3739.             wobj = GetChildHndl(gWindowFormats, --i);
  3740.             attr = mDerefWFMT(wobj)->attributes;
  3741.             if (attr & kwRuntimeOnlyDoc) {
  3742.                 if (attr & kwAutoNew) {
  3743.                     err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  3744.                     if (err) break;
  3745.                 }
  3746.             }
  3747.         }
  3748.     }
  3749.     return(err);
  3750. }
  3751.  
  3752.  
  3753.  
  3754. /*****************************************************************************/
  3755.  
  3756.  
  3757.  
  3758. /* This call can be done as two separate calls.  However, this function does both
  3759. ** functions of creating the document, and then giving the document a window.  It
  3760. ** also handles errors and puts up an error window if something goes wrong. */
  3761.  
  3762. #pragma segment Window
  3763. OSErr    NewDocumentWindow(FileRecHndl *frHndl, OSType sftype, Boolean incTitleNum)
  3764. {
  3765.     FileRecHndl    ff, *ffp;
  3766.     OSErr        err;
  3767.     short        i, numAdded;
  3768.  
  3769.     gCursorPtr = nil;        /* Force recalc of cursor. */
  3770.  
  3771.     ffp = (frHndl) ? frHndl : &ff;
  3772.     *ffp = nil;
  3773.  
  3774.     if (!gWindowFormats) return(noErr);
  3775.  
  3776.     err = GetSeparateWFMT(sftype, &numAdded);
  3777.     if (!err) {
  3778.         for (i = (*gWindowFormats)->numChildren; i;) {
  3779.             if (sftype == mDerefWFMT(GetChildHndl(gWindowFormats, --i))->sfType) {
  3780.                 err = NewDocument(ffp, sftype, incTitleNum);
  3781.                 if (!err) {
  3782.                     err = DoNewWindow(*ffp, nil, FrontWindowOfType(kwIsDocument, true), (WindowPtr)-1);
  3783.                     if (err) DisposeDocument(*ffp);
  3784.                 }
  3785.                 break;
  3786.             }
  3787.         }
  3788.     }
  3789.     GetSeparateWFMT(0, &numAdded);
  3790.  
  3791.     return(err);
  3792. }
  3793.  
  3794.  
  3795.  
  3796. /*****************************************************************************/
  3797.  
  3798.  
  3799.  
  3800. /* This call can be done as two separate calls.  However, this function does both
  3801. ** functions of creating the document, and then giving the document a window.  It
  3802. ** also handles errors and puts up an error window if something goes wrong. */
  3803.  
  3804. #pragma segment Window
  3805. OSErr    OpenDocumentWindow(FileRecHndl *frHndl, FSSpecPtr fileToOpen, char permission)
  3806. {
  3807.     FileRecHndl    ff, *ffp;
  3808.     OSErr        err;
  3809.  
  3810.     gCursorPtr = nil;        /* Force recalc of cursor. */
  3811.  
  3812.     ffp = (frHndl) ? frHndl : &ff;
  3813.     *ffp = nil;
  3814.  
  3815.     if (!gWindowFormats) return(noErr);
  3816.  
  3817.     err = OpenDocument(ffp, fileToOpen, permission);
  3818.     if (!err) {
  3819.         err = DoNewWindow(*ffp, nil, FrontWindowOfType(kwIsDocument, true), (WindowPtr)-1);
  3820.         if (err) DisposeDocument(*ffp);
  3821.     }
  3822.  
  3823.     return(err);
  3824. }
  3825.  
  3826.  
  3827.  
  3828.